<!DOCTYPE html>
<html lang=en>
<head>
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, minimal-ui">
  <meta name="renderer" content="webkit">
  <meta http-equiv="Cache-Control" content="no-transform" />
  <meta http-equiv="Cache-Control" content="no-siteapp" />
  <meta name="apple-mobile-web-app-capable" content="yes">
  <meta name="apple-mobile-web-app-status-bar-style" content="black">
  <meta name="format-detection" content="telephone=no,email=no,adress=no">
  <!-- Color theme for statusbar -->
  <meta name="theme-color" content="#000000" />
  <!-- 强制页面在当前窗口以独立页面显示,防止别人在框架里调用页面 -->
  <meta http-equiv="window-target" content="_top" />
  
  
  <title>JavaScript设计模式-学习 | Hexo</title>
  <script src="/js/jQuery.md5.js"></script>
  <script>
    
    (function(){
      localStorage.setItem('userinfo',hex_md5('123chen'))
      
      var localData = localStorage.getItem("userinfo");
      // var localState = localStorage.getItem("state");
        if(localStorage.getItem("state") === null){
          var reason = window.prompt('请输入访问密码');
          // var promptVal = window.prompt('请输入访问密码');
          if(reason){
              //填写内容并“确定”
              var md5Prompt = hex_md5(reason)
              //点击的是“确定” 
              if (localData !== md5Prompt){
                alert('密码错误！');
                // history.back();
                location.replace(location.href); 
              }else{
                // alert('0123');
                localStorage.setItem('state',"1")
              }
          }
          else if(reason === ""){
              //未填写但“确定”
              location.replace(location.href); 
          }
          else{
            //“取消”事件
            location.replace(location.href); 
          }
        }

    })();
  </script>
 <link rel="alternate" href="/atom.xml" data="123chen" type="application/atom+xml">
  <meta name="description" content="JavaScript设计模式learn-javascript-design-pattern学习javascript设计模式，记录的小例子~ 第一篇 - 面对对象编程 第一章 灵活的语言————javascript 第二章 面对对象编程  第二篇 - 创建型设计模式 第三章 简单工厂模式 第四章 工厂方法模式 第五章 抽象工厂模式 第六章 建造者模式 第七章 原型模式 第八章 单例模式  第三篇 -">
<meta property="og:type" content="article">
<meta property="og:title" content="JavaScript设计模式-学习">
<meta property="og:url" content="http://yoursite.com/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/index.html">
<meta property="og:site_name" content="学习的敌人是自己的满足，要认真学习一点东西，必须从不自满开始。对自己，“学而不厌”，对人家，“诲人不倦”，我们应取这种态度。">
<meta property="og:description" content="JavaScript设计模式learn-javascript-design-pattern学习javascript设计模式，记录的小例子~ 第一篇 - 面对对象编程 第一章 灵活的语言————javascript 第二章 面对对象编程  第二篇 - 创建型设计模式 第三章 简单工厂模式 第四章 工厂方法模式 第五章 抽象工厂模式 第六章 建造者模式 第七章 原型模式 第八章 单例模式  第三篇 -">
<meta property="og:locale" content="en_US">
<meta property="article:published_time" content="2019-11-24T01:12:57.000Z">
<meta property="article:modified_time" content="2020-03-27T12:41:28.972Z">
<meta property="article:author" content="溟海">
<meta property="article:tag" content="JavaScript">
<meta property="article:tag" content="JavaScript设计模式">
<meta name="twitter:card" content="summary">
  <!-- Canonical links -->
  <link rel="canonical" href="http://yoursite.com/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/index.html">
  
    <link rel="alternate" href="/atom.xml" title="学习的敌人是自己的满足，要认真学习一点东西，必须从不自满开始。对自己，“学而不厌”，对人家，“诲人不倦”，我们应取这种态度。" type="application/atom+xml">
  
  
    <link rel="icon" href="/favicon.png" type="image/x-icon">
  
  
<link rel="stylesheet" href="/css/style.css">

  
  
  
  
<meta name="generator" content="Hexo 4.2.0"></head>


<body class="main-center" itemscope itemtype="http://schema.org/WebPage">
  <header class="header" itemscope itemtype="http://schema.org/WPHeader">
  <div class="slimContent">
    <div class="navbar-header">
      
      
      <div class="profile-block text-center">
        <a id="avatar" href="https://github.com/chen08" target="_blank">
          <img class="img-circle img-rotate" src="/images/avatar.jpg" width="200" height="200">
        </a>
        <h2 id="name" class="hidden-xs hidden-sm">溟海</h2>
        <h3 id="title" class="hidden-xs hidden-sm hidden-md">Web Developer &amp; Designer</h3>
        <small id="location" class="text-muted hidden-xs hidden-sm"><i class="icon icon-map-marker"></i> Guangzhou, China</small>
      </div>
      
      <div class="search" id="search-form-wrap">

    <form class="search-form sidebar-form">
        <div class="input-group">
            <input type="text" class="search-form-input form-control" placeholder="Search" />
            <span class="input-group-btn">
                <button type="submit" class="search-form-submit btn btn-flat" onclick="return false;"><i class="icon icon-search"></i></button>
            </span>
        </div>
    </form>
    <div class="ins-search">
  <div class="ins-search-mask"></div>
  <div class="ins-search-container">
    <div class="ins-input-wrapper">
      <input type="text" class="ins-search-input" placeholder="Type something..." x-webkit-speech />
      <button type="button" class="close ins-close ins-selectable" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
    </div>
    <div class="ins-section-wrapper">
      <div class="ins-section-container"></div>
    </div>
  </div>
</div>


</div>
      <button class="navbar-toggle collapsed" type="button" data-toggle="collapse" data-target="#main-navbar" aria-controls="main-navbar" aria-expanded="false">
        <span class="sr-only">Toggle navigation</span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
        <span class="icon-bar"></span>
      </button>
    </div>
    <nav id="main-navbar" class="collapse navbar-collapse" itemscope itemtype="http://schema.org/SiteNavigationElement" role="navigation">
      <ul class="nav navbar-nav main-nav ">
        
        
          <!-- . -->
        
        
          <li class="menu-item menu-item-home">
            <a href="/.">
              
              <i class="icon icon-home-fill"></i>
              
              <span class="menu-title">Home</span>
            </a>
          </li>
        


        
          <!-- archives -->
        
        
          <li class="menu-item menu-item-archives">
            <a href="/archives">
              
              <i class="icon icon-archives-fill"></i>
              
              <span class="menu-title">Archives</span>
            </a>
          </li>
        


        
          <!-- categories -->
        
        
          <li class="menu-item menu-item-categories">
            <a href="/categories">
              
              <i class="icon icon-folder"></i>
              
              <span class="menu-title">Categories</span>
            </a>
          </li>
        


        
          <!-- tags -->
        
        
          <li class="menu-item menu-item-tags">
            <a href="/tags">
              
              <i class="icon icon-tags"></i>
              
              <span class="menu-title">Tags</span>
            </a>
          </li>
        


        
          <!-- repository -->
        
        
          <li class="menu-item menu-item-repository">
            <a href="/repository">
              
              <i class="icon icon-project"></i>
              
              <span class="menu-title">Repository</span>
            </a>
          </li>
        


        
          <!-- books -->
        
        
          <li class="menu-item menu-item-books">
            <a href="/books">
              
              <i class="icon icon-book-fill"></i>
              
              <span class="menu-title">Books</span>
            </a>
          </li>
        


        
          <!-- links -->
        
        
          <li class="menu-item menu-item-links">
            <a href="/links">
              
              <i class="icon icon-friendship"></i>
              
              <span class="menu-title">Links</span>
            </a>
          </li>
        


        
          <!-- about -->
        
        
          <li class="menu-item menu-item-about">
            <a href="/about">
              
              <i class="icon icon-cup-fill"></i>
              
              <span class="menu-title">About</span>
            </a>
          </li>
        


        
          <!-- navigation/webstack/index.html -->
        
        
          <li class="menu-item menu-item-navigation">
            <a href="/navigation/webstack/index.html">
              
              <i class="icon icon-delicious"></i>
              
              <span class="menu-title">Navigation</span>
            </a>
          </li>
        


        
          <!-- navigation/webstack/word.html -->
        
        
          <li style="display: none;" class="menu-item menu-item-fixed">
            <a href="/navigation/webstack/word.html">
              
              <i class="icon icon-delicious"></i>
              
              <span class="menu-title">menu.fixed</span>
            </a>
          </li>
        


        
      </ul>

      
	
    <ul class="social-links">
    	
        <li><a href="https://github.com/cofess" target="_blank" title="Github" data-toggle=tooltip data-placement=top><i class="icon icon-github"></i></a></li>
        
        <li><a href="http://weibo.com/cofess" target="_blank" title="Weibo" data-toggle=tooltip data-placement=top><i class="icon icon-weibo"></i></a></li>
        
        <li><a href="https://twitter.com/iwebued" target="_blank" title="Twitter" data-toggle=tooltip data-placement=top><i class="icon icon-twitter"></i></a></li>
        
        <li><a href="https://www.behance.net/cofess" target="_blank" title="Behance" data-toggle=tooltip data-placement=top><i class="icon icon-behance"></i></a></li>
        
        <li><a href="/atom.xml" target="_blank" title="Rss" data-toggle=tooltip data-placement=top><i class="icon icon-rss"></i></a></li>
        
    </ul>

    </nav>
  </div>
</header>

  
    <aside class="sidebar" itemscope itemtype="http://schema.org/WPSideBar">
  <div class="slimContent">
    
      <div class="widget">
    <h3 class="widget-title">Board</h3>
    <div class="widget-body">
        <div id="board">
            <div class="content">
                <p>欢迎交流与分享经验!</p>
            </div>
        </div>
    </div>
</div>

    
      
  <div class="widget">
    <h3 class="widget-title">Categories</h3>
    <div class="widget-body">
      <ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/1-WEB%E5%89%8D%E7%AB%AF/">1.WEB前端</a><span class="category-list-count">15</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/2-%E7%BC%96%E7%A8%8B%E8%AF%AD%E8%A8%80/">2.编程语言</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/3-%E4%BA%A7%E5%93%81%E8%AE%BE%E8%AE%A1/">3.产品设计</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/4-%E7%AE%A1%E7%90%86%E8%90%A5%E9%94%80/">4.管理营销</a><span class="category-list-count">6</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/5-%E6%8A%80%E8%83%BD%E6%8F%90%E5%8D%87/">5.技能提升</a><span class="category-list-count">16</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/6-%E8%AF%BB%E4%B9%A6%E6%80%BB%E7%BB%93/">6.读书总结</a><span class="category-list-count">8</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">Tags</h3>
    <div class="widget-body">
      <ul class="tag-list" itemprop="keywords"><li class="tag-list-item"><a class="tag-list-link" href="/tags/JavaScript/" rel="tag">JavaScript</a><span class="tag-list-count">15</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/JavaScript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="tag">JavaScript设计模式</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/Office/" rel="tag">Office</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/PHP/" rel="tag">PHP</a><span class="tag-list-count">3</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%86%99%E4%BD%9C/" rel="tag">写作</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%9F%BA%E9%87%91/" rel="tag">基金</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%AD%A6%E4%B9%A0/" rel="tag">学习</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E5%B7%A5%E4%BD%9C/" rel="tag">工作</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%80%9D%E8%80%83/" rel="tag">思考</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E6%B8%85%E5%8D%95/" rel="tag">清单</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%9B%AE%E6%A0%87/" rel="tag">目标</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E7%BB%83%E4%B9%A0/" rel="tag">练习</a><span class="tag-list-count">1</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E8%8B%B1%E8%AF%AD/" rel="tag">英语</a><span class="tag-list-count">6</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E8%AE%A1%E5%88%92/" rel="tag">计划</a><span class="tag-list-count">2</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E8%AF%AD%E6%B3%95/" rel="tag">语法</a><span class="tag-list-count">4</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%9A%8F%E7%AC%94/" rel="tag">随笔</a><span class="tag-list-count">8</span></li><li class="tag-list-item"><a class="tag-list-link" href="/tags/%E9%9D%A2%E8%AF%95/" rel="tag">面试</a><span class="tag-list-count">1</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">Tag Cloud</h3>
    <div class="widget-body tagcloud">
      <a href="/tags/JavaScript/" style="font-size: 14px;">JavaScript</a> <a href="/tags/JavaScript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" style="font-size: 13px;">JavaScript设计模式</a> <a href="/tags/Office/" style="font-size: 13.33px;">Office</a> <a href="/tags/PHP/" style="font-size: 13.33px;">PHP</a> <a href="/tags/%E5%86%99%E4%BD%9C/" style="font-size: 13.17px;">写作</a> <a href="/tags/%E5%9F%BA%E9%87%91/" style="font-size: 13.17px;">基金</a> <a href="/tags/%E5%AD%A6%E4%B9%A0/" style="font-size: 13px;">学习</a> <a href="/tags/%E5%B7%A5%E4%BD%9C/" style="font-size: 13px;">工作</a> <a href="/tags/%E6%80%9D%E8%80%83/" style="font-size: 13px;">思考</a> <a href="/tags/%E6%B8%85%E5%8D%95/" style="font-size: 13px;">清单</a> <a href="/tags/%E7%9B%AE%E6%A0%87/" style="font-size: 13px;">目标</a> <a href="/tags/%E7%BB%83%E4%B9%A0/" style="font-size: 13px;">练习</a> <a href="/tags/%E8%8B%B1%E8%AF%AD/" style="font-size: 13.67px;">英语</a> <a href="/tags/%E8%AE%A1%E5%88%92/" style="font-size: 13.17px;">计划</a> <a href="/tags/%E8%AF%AD%E6%B3%95/" style="font-size: 13.5px;">语法</a> <a href="/tags/%E9%9A%8F%E7%AC%94/" style="font-size: 13.83px;">随笔</a> <a href="/tags/%E9%9D%A2%E8%AF%95/" style="font-size: 13px;">面试</a>
    </div>
  </div>

    
      
  <div class="widget">
    <h3 class="widget-title">Archive</h3>
    <div class="widget-body">
      <ul class="archive-list"><li class="archive-list-item"><a class="archive-list-link" href="/archives/20120/04/">April 20120</a><span class="archive-list-count">6</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/20120/03/">March 20120</a><span class="archive-list-count">2</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/05/">May 2020</a><span class="archive-list-count">4</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/04/">April 2020</a><span class="archive-list-count">12</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2020/03/">March 2020</a><span class="archive-list-count">14</span></li><li class="archive-list-item"><a class="archive-list-link" href="/archives/2019/11/">November 2019</a><span class="archive-list-count">10</span></li></ul>
    </div>
  </div>


    
      
  <div class="widget">
    <h3 class="widget-title">Recent Posts</h3>
    <div class="widget-body">
      <ul class="recent-post-list list-unstyled no-thumbnail">
        
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/categories/5-%E6%8A%80%E8%83%BD%E6%8F%90%E5%8D%87/">5.技能提升</a>
              </p>
              <p class="item-title">
                <a href="/20120/04/21/05/fund/%E5%9F%BA%E9%87%91%E5%9F%BA%E7%A1%80/" class="title">基金基础</a>
              </p>
              <p class="item-date">
                <time datetime="+020120-04-21T01:12:57.000Z" itemprop="datePublished">20120-04-21</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/categories/5-%E6%8A%80%E8%83%BD%E6%8F%90%E5%8D%87/">5.技能提升</a>
              </p>
              <p class="item-title">
                <a href="/20120/04/21/05/study/%E5%AD%A6%E4%B9%A0/" class="title">学习</a>
              </p>
              <p class="item-date">
                <time datetime="+020120-04-21T01:12:57.000Z" itemprop="datePublished">20120-04-21</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/categories/5-%E6%8A%80%E8%83%BD%E6%8F%90%E5%8D%87/">5.技能提升</a>
              </p>
              <p class="item-title">
                <a href="/20120/04/13/05/%E4%BB%8A%E6%97%A5%E8%AE%A1%E5%88%92/" class="title">今日计划</a>
              </p>
              <p class="item-date">
                <time datetime="+020120-04-13T01:12:57.000Z" itemprop="datePublished">20120-04-13</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/categories/5-%E6%8A%80%E8%83%BD%E6%8F%90%E5%8D%87/">5.技能提升</a>
              </p>
              <p class="item-title">
                <a href="/20120/04/03/05/office/Excel%E5%AD%A6%E4%B9%A0/" class="title">Excel学习</a>
              </p>
              <p class="item-date">
                <time datetime="+020120-04-03T01:12:57.000Z" itemprop="datePublished">20120-04-03</time>
              </p>
            </div>
          </li>
          
          <li>
            
            <div class="item-inner">
              <p class="item-category">
                <a class="category-link" href="/categories/5-%E6%8A%80%E8%83%BD%E6%8F%90%E5%8D%87/">5.技能提升</a>
              </p>
              <p class="item-title">
                <a href="/20120/04/03/05/office/PPT%E5%AD%A6%E4%B9%A0/" class="title">PPT学习</a>
              </p>
              <p class="item-date">
                <time datetime="+020120-04-03T01:12:57.000Z" itemprop="datePublished">20120-04-03</time>
              </p>
            </div>
          </li>
          
      </ul>
    </div>
  </div>
  

    
  </div>
</aside>

  
  
<aside class="sidebar sidebar-toc collapse" id="collapseToc" itemscope itemtype="http://schema.org/WPSideBar">
  <span class="toggle-btn-absolute">
    <a class="toggle-btn" data-toggle="collapse" href="#collapseToc" aria-expanded="true" title="Catalogue" role="button">
      <i class="text-in icon icon-close"></i>
    </a>
  </span>
  <div class="slimContent">
    <nav id="toc" class="article-toc">
      <h3 class="toc-title">Catalogue</h3>
      <ol class="toc"><li class="toc-item toc-level-1"><a class="toc-link" href="#JavaScript设计模式"><span class="toc-number">1.</span> <span class="toc-text">JavaScript设计模式</span></a></li><li class="toc-item toc-level-1"><a class="toc-link" href="#learn-javascript-design-pattern"><span class="toc-number">2.</span> <span class="toc-text">learn-javascript-design-pattern</span></a><ol class="toc-child"><li class="toc-item toc-level-3"><a class="toc-link" href="#第一篇-面对对象编程"><span class="toc-number">2.0.1.</span> <span class="toc-text">第一篇 - 面对对象编程</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#第二篇-创建型设计模式"><span class="toc-number">2.0.2.</span> <span class="toc-text">第二篇 - 创建型设计模式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#第三篇-结构型设计模式"><span class="toc-number">2.0.3.</span> <span class="toc-text">第三篇 - 结构型设计模式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#第四篇-行为型设计模式"><span class="toc-number">2.0.4.</span> <span class="toc-text">第四篇 - 行为型设计模式</span></a></li><li class="toc-item toc-level-3"><a class="toc-link" href="#第五篇-技巧型设计模式"><span class="toc-number">2.0.5.</span> <span class="toc-text">第五篇 - 技巧型设计模式</span></a></li></ol></li></ol></li><li class="toc-item toc-level-1"><a class="toc-link" href="#The-MIT-License-MIT"><span class="toc-number">3.</span> <span class="toc-text">The MIT License (MIT)</span></a><ol class="toc-child"><li class="toc-item toc-level-2"><a class="toc-link" href="#第一章"><span class="toc-number">3.1.</span> <span class="toc-text">第一章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二章"><span class="toc-number">3.2.</span> <span class="toc-text">第二章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三章"><span class="toc-number">3.3.</span> <span class="toc-text">第三章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第四章"><span class="toc-number">3.4.</span> <span class="toc-text">第四章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第五章"><span class="toc-number">3.5.</span> <span class="toc-text">第五章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第六章"><span class="toc-number">3.6.</span> <span class="toc-text">第六章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第七章"><span class="toc-number">3.7.</span> <span class="toc-text">第七章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第八章"><span class="toc-number">3.8.</span> <span class="toc-text">第八章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第九章"><span class="toc-number">3.9.</span> <span class="toc-text">第九章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十章"><span class="toc-number">3.10.</span> <span class="toc-text">第十章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十二章"><span class="toc-number">3.11.</span> <span class="toc-text">第十二章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十三章"><span class="toc-number">3.12.</span> <span class="toc-text">第十三章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十四章"><span class="toc-number">3.13.</span> <span class="toc-text">第十四章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十五章"><span class="toc-number">3.14.</span> <span class="toc-text">第十五章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十六章"><span class="toc-number">3.15.</span> <span class="toc-text">第十六章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十七章"><span class="toc-number">3.16.</span> <span class="toc-text">第十七章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十八章"><span class="toc-number">3.17.</span> <span class="toc-text">第十八章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第十九章"><span class="toc-number">3.18.</span> <span class="toc-text">第十九章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十章"><span class="toc-number">3.19.</span> <span class="toc-text">第二十章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十一章"><span class="toc-number">3.20.</span> <span class="toc-text">第二十一章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十二章"><span class="toc-number">3.21.</span> <span class="toc-text">第二十二章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十三章"><span class="toc-number">3.22.</span> <span class="toc-text">第二十三章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十四章"><span class="toc-number">3.23.</span> <span class="toc-text">第二十四章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十五章"><span class="toc-number">3.24.</span> <span class="toc-text">第二十五章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十六章"><span class="toc-number">3.25.</span> <span class="toc-text">第二十六章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十七章"><span class="toc-number">3.26.</span> <span class="toc-text">第二十七章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十八章"><span class="toc-number">3.27.</span> <span class="toc-text">第二十八章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第二十九章"><span class="toc-number">3.28.</span> <span class="toc-text">第二十九章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十章"><span class="toc-number">3.29.</span> <span class="toc-text">第三十章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十一章"><span class="toc-number">3.30.</span> <span class="toc-text">第三十一章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十二章"><span class="toc-number">3.31.</span> <span class="toc-text">第三十二章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十三章"><span class="toc-number">3.32.</span> <span class="toc-text">第三十三章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十四章"><span class="toc-number">3.33.</span> <span class="toc-text">第三十四章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十五章"><span class="toc-number">3.34.</span> <span class="toc-text">第三十五章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十六章"><span class="toc-number">3.35.</span> <span class="toc-text">第三十六章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十七章"><span class="toc-number">3.36.</span> <span class="toc-text">第三十七章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十八章"><span class="toc-number">3.37.</span> <span class="toc-text">第三十八章</span></a></li><li class="toc-item toc-level-2"><a class="toc-link" href="#第三十九章"><span class="toc-number">3.38.</span> <span class="toc-text">第三十九章</span></a></li></ol></li></ol>
    </nav>
  </div>
</aside>

<main class="main" role="main">
  <!-- 引入百度的思维导图库 -->
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kity@2.0.4/dist/kity.min.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/kityminder-core@1.4.50/dist/kityminder.core.min.js"></script>
<script defer="true" type="text/javascript" src="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.js"></script>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/hexo-simple-mindmap@0.2.0/dist/mindmap.min.css">
<!-- 引入百度的思维导图库 -->
<div class="content">
  <article id="post-01/javascript设计模式" class="article article-type-post" itemscope itemtype="http://schema.org/BlogPosting">
    
    <div class="article-header">
      
        
  
    <h1 class="article-title" itemprop="name">
      JavaScript设计模式-学习
    </h1>
  

      
      <div class="article-meta">
        <span class="article-date">
    <i class="icon icon-calendar-check"></i>
	<a href="/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" class="article-date">
	  <time datetime="2019-11-24T01:12:57.000Z" itemprop="datePublished">2019-11-24</time>
	</a>
</span>
        
  <span class="article-category">
    <i class="icon icon-folder"></i>
    <a class="article-category-link" href="/categories/1-WEB%E5%89%8D%E7%AB%AF/">1.WEB前端</a>
  </span>

        
  <span class="article-tag">
    <i class="icon icon-tags"></i>
	<a class="article-tag-link" href="/tags/JavaScript/" rel="tag">JavaScript</a>, <a class="article-tag-link" href="/tags/JavaScript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" rel="tag">JavaScript设计模式</a>
  </span>


        

	<span class="article-read hidden-xs">
    	<i class="icon icon-eye-fill" aria-hidden="true"></i>
    	<span id="/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" class="leancloud_visitors"  data-flag-title="JavaScript设计模式-学习">0</span>
    </span>

        <span class="post-comment"><i class="icon icon-comment"></i> <a href="/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/#comments" class="article-comment-link">Comments</a></span>
        
	
		<span class="post-wordcount hidden-xs" itemprop="wordCount">Word Count: 19.5k(words)</span>
	
	
		<span class="post-readcount hidden-xs" itemprop="timeRequired">Read Count: 93(minutes)</span>
	

      </div>
    </div>
    <div class="article-entry marked-body" itemprop="articleBody">
      
        <h1 id="JavaScript设计模式"><a href="#JavaScript设计模式" class="headerlink" title="JavaScript设计模式"></a>JavaScript设计模式</h1><h1 id="learn-javascript-design-pattern"><a href="#learn-javascript-design-pattern" class="headerlink" title="learn-javascript-design-pattern"></a>learn-javascript-design-pattern</h1><p>学习javascript设计模式，记录的小例子~</p>
<h3 id="第一篇-面对对象编程"><a href="#第一篇-面对对象编程" class="headerlink" title="第一篇 - 面对对象编程"></a>第一篇 - 面对对象编程</h3><ul>
<li><a href="#第一章">第一章</a> 灵活的语言————javascript</li>
<li><a href="#第二章">第二章</a> 面对对象编程</li>
</ul>
<h3 id="第二篇-创建型设计模式"><a href="#第二篇-创建型设计模式" class="headerlink" title="第二篇 - 创建型设计模式"></a>第二篇 - 创建型设计模式</h3><ul>
<li><a href="#第三章">第三章</a> 简单工厂模式</li>
<li><a href="#第四章">第四章</a> 工厂方法模式</li>
<li><a href="#第五章">第五章</a> 抽象工厂模式</li>
<li><a href="#第六章">第六章</a> 建造者模式</li>
<li><a href="#第七章">第七章</a> 原型模式</li>
<li><a href="#第八章">第八章</a> 单例模式</li>
</ul>
<h3 id="第三篇-结构型设计模式"><a href="#第三篇-结构型设计模式" class="headerlink" title="第三篇 - 结构型设计模式"></a>第三篇 - 结构型设计模式</h3><ul>
<li><a href="#第九章">第九章</a> 外观模式</li>
<li><a href="#第十章">第十章</a> 适配器模式</li>
<li><a href="#第十一章">第十一章</a> 代理模式</li>
<li><a href="#第十二章">第十二章</a> 装饰者模式</li>
<li><a href="#第十三章">第十三章</a> 桥接模式</li>
<li><a href="#第十四章">第十四章</a> 组合模式</li>
<li><a href="#第十五章">第十五章</a> 享元模式</li>
</ul>
<h3 id="第四篇-行为型设计模式"><a href="#第四篇-行为型设计模式" class="headerlink" title="第四篇 - 行为型设计模式"></a>第四篇 - 行为型设计模式</h3><ul>
<li><a href="#第十六章">第十六章</a> 模板方法模式</li>
<li><a href="#第十七章">第十七章</a> 观察者模式</li>
<li><a href="#第十八章">第十八章</a> 状态模式</li>
<li><a href="#第十九章">第十九章</a> 策略模式</li>
<li><a href="#第二十章">第二十章</a> 责任链模式</li>
<li><a href="#第二十一章">第二十一章</a> 命令模式</li>
<li><a href="#第二十二章">第二十二章</a> 访问者模式</li>
<li><a href="#第二十三章">第二十三章</a> 中介者模式</li>
<li><a href="#第二十四章">第二十四章</a> 备忘录模式</li>
<li><a href="#第二十五章">第二十五章</a> 迭代器模式</li>
<li><a href="#第二十六章">第二十六章</a> 解释器模式</li>
</ul>
<h3 id="第五篇-技巧型设计模式"><a href="#第五篇-技巧型设计模式" class="headerlink" title="第五篇 - 技巧型设计模式"></a>第五篇 - 技巧型设计模式</h3><ul>
<li><a href="#第二十七章">第二十七章</a> 链模式</li>
<li><a href="#第二十八章">第二十八章</a> 委托模式</li>
<li><a href="#第二十九章">第二十九章</a> 数据访问对象模式</li>
<li><a href="#第三十章">第三十章</a> 节流模式</li>
<li><a href="#第三十一章">第三十一章</a> 简单模板模式</li>
<li><a href="#第三十二章">第三十二章</a> 惰性模式</li>
<li><a href="#第三十三章">第三十三章</a> 参与者模式</li>
<li><a href="#第三十四章">第三十四章</a> 等待者模式</li>
<li><a href="#第三十五章">第三十五章</a> 同步模块模式</li>
<li><a href="#第三十六章">第三十六章</a> 异步模块模式</li>
<li><a href="#第三十七章">第三十七章</a> Widget模式（其实是实现一个模板引擎）</li>
<li><a href="#第三十八章">第三十八章</a> MVC模式</li>
<li><a href="#第三十九章">第三十九章</a> MVP模式</li>
<li>第四十章 MVVM模式</li>
</ul>
<h1 id="The-MIT-License-MIT"><a href="#The-MIT-License-MIT" class="headerlink" title="The MIT License (MIT)"></a>The MIT License (MIT)</h1><p>Copyright (c) 2015 Berwin</p>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy<br>of this software and associated documentation files (the “Software”), to deal<br>in the Software without restriction, including without limitation the rights<br>to use, copy, modify, merge, publish, distribute, sublicense, and/or sell<br>copies of the Software, and to permit persons to whom the Software is<br>furnished to do so, subject to the following conditions:</p>
<p>The above copyright notice and this permission notice shall be included in all<br>copies or substantial portions of the Software.</p>
<p>THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR<br>IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,<br>FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE<br>AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER<br>LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,<br>OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE<br>SOFTWARE.</p>
<h2 id="第一章"><a href="#第一章" class="headerlink" title="第一章"></a>第一章</h2><p>灵活的语言————javascript</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> check = &#123;</span><br><span class="line">  checkName: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 验证姓名</span></span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  checkEmail: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 验证邮箱</span></span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  checkPassword: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 验证密码</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> ck = check.checkName();</span><br><span class="line"><span class="built_in">console</span>.log( ck );</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> check = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    checkName: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 验证姓名</span></span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    checkEmail: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 验证邮箱</span></span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    checkPassword: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 验证密码</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = check();</span><br><span class="line">a.checkName();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Check = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.checkName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'验证姓名'</span>);</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.checkEmail = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验邮箱'</span>);</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.checkPassword = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验密码'</span>);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> Check();</span><br><span class="line">a.checkName();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Check = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">Check.prototype = &#123;</span><br><span class="line">  checkName: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验姓名'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  checkEmail: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验邮箱'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  checkPassword: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验密码'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> Check();</span><br><span class="line">a.checkName();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Check = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">Check.prototype = &#123;</span><br><span class="line">  checkName: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验姓名'</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  checkEmail: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验邮箱'</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  checkPassword: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'校验密码'</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> Check();</span><br><span class="line">a.checkName().checkEmail().checkPassword();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="built_in">Function</span>.prototype.addMethod = <span class="function"><span class="keyword">function</span>(<span class="params">name, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.prototype[name] = fn;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Methods = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">Methods.addMethod(<span class="string">'checkName'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'校验姓名'</span>);</span><br><span class="line">&#125;).addMethod(<span class="string">'checkEmail'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'校验邮箱'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> Methods();</span><br><span class="line">a.checkName();</span><br></pre></td></tr></table></figure>

<blockquote>
<p>关于函数里的Function.prototype的问题？</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">Function</span>.prototype.addMethod = <span class="function"><span class="keyword">function</span>(<span class="params">name, fn</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (!<span class="keyword">this</span>.prototype[name]) &#123;</span><br><span class="line">        <span class="keyword">this</span>.prototype[name] = fn;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> Methods = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">Methods</span><br><span class="line">    .addMethod(<span class="string">'checkName'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;)</span><br><span class="line">    .addMethod(<span class="string">'checkMail'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;)</span><br><span class="line"><span class="keyword">var</span> m = <span class="keyword">new</span> Methods();</span><br><span class="line">m.checkName().checkMail();</span><br></pre></td></tr></table></figure>

<blockquote>
<p>这样一段代码，实际上和下面这段代码是不是等价的？</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> CheckObject = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;</span><br><span class="line">CheckObject.prototype = &#123;</span><br><span class="line">    checkName: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;,</span><br><span class="line">    checkEmail: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> CheckObject();</span><br><span class="line">a.checkName().checkEmail();</span><br></pre></td></tr></table></figure>
<p>都是给目标函数添加了两个方法：checkName和checkMail，从最终效果来看两种方法实现的作用都是一样的。</p>
<p>两种方法各有什么优势呢？或者说第一种方法好在哪里？他给原生js添加了一个方法addMethod，不会污染原生的JS吗？</p>
<blockquote>
<p>回答:<br>第一种写法是在Function构造函数的原型上添加方法addMethod。</p>
</blockquote>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Methods = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br></pre></td></tr></table></figure>
<p>等价于</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">var</span> Methods = <span class="keyword">new</span> <span class="built_in">Function</span>();</span><br></pre></td></tr></table></figure>
<p>所以Methods继承了Function原型上的方法。在后面 var m = new Methods()的时候，m也继承了Function上的方法。<br>这种写法如果你希望你每一个实例都想继承一个共有的方法，可以这么写。如果仅仅是希望在某一个构造函数的实例继承这个方法，就应该使用下面的那种写法。</p>
<figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="keyword">var</span> CheckObject = <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;&#125;;</span><br><span class="line">CheckObject.prototype = &#123;</span><br><span class="line">    <span class="keyword">constructor</span> : CheckObject,</span><br><span class="line">    checkName: function()&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;,</span><br><span class="line">    checkEmail: <span class="function"><span class="keyword">function</span>(<span class="params"></span>)</span>&#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>这种写法是只在构造函数CheckObject的原型上添加方法，所以只有它的实例才会继承到这些方法。</p>
<blockquote>
<p>第一种方法，节省了addMethod在函数对象上的重复定义，自己用没事，冲突时可以直接在对象上重复定义，覆盖上一级Function原型上的addMethod，也谈不上污染。但是给别人用可能会引起冲突，因为你改了大家公用的东西。</p>
</blockquote>
<h2 id="第二章"><a href="#第二章" class="headerlink" title="第二章"></a>第二章</h2><p>面对对象编程</p>
<ul>
<li>1.js - 闭包</li>
<li>2.js - 创建对象的安全模式</li>
<li>3.js - 类式继承（有缺陷的继承，不推荐使用）</li>
<li>4.js - 构造函数继承（有缺陷的继承，不推荐使用）</li>
<li>5.js - 组合继承（有缺陷）</li>
<li>6.js - 终极继承者</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Book = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 私有属性</span></span><br><span class="line">  <span class="keyword">var</span> bookNum = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 私有方法</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">checkBook</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">_book</span>(<span class="params">newID, newName, newPrice</span>) </span>&#123;</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 私有变量</span></span><br><span class="line">    <span class="keyword">var</span> name, price;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 静态私有方法</span></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">checkID</span>(<span class="params">id</span>) </span>&#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 特权方法</span></span><br><span class="line">    <span class="keyword">this</span>.getName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">    <span class="keyword">this</span>.getPrice = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">    <span class="keyword">this</span>.setName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">    <span class="keyword">this</span>.setPrice = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 公有属性</span></span><br><span class="line">    <span class="keyword">this</span>.id = newID;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 公有方法</span></span><br><span class="line">    <span class="keyword">this</span>.copy = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">    bookNum++;</span><br><span class="line">    <span class="keyword">if</span>(bookNum &gt; <span class="number">100</span>) &#123;</span><br><span class="line">      <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'我们仅出版100本书。'</span>);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 构造器</span></span><br><span class="line">    <span class="keyword">this</span>.setName(name);</span><br><span class="line">    <span class="keyword">this</span>.setPrice(price);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  _book.prototype = &#123;</span><br><span class="line">    <span class="comment">// 静态公有属性</span></span><br><span class="line">    isJSBook: <span class="literal">false</span>,</span><br><span class="line">    </span><br><span class="line">    <span class="comment">// 静态公有方法</span></span><br><span class="line">    display: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> _book;</span><br><span class="line"></span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Book = <span class="function"><span class="keyword">function</span>(<span class="params">title, time, type</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span> <span class="keyword">instanceof</span> Book) &#123;</span><br><span class="line">    <span class="keyword">this</span>.title = title;</span><br><span class="line">    <span class="keyword">this</span>.time = time;</span><br><span class="line">    <span class="keyword">this</span>.type = type;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Book(title, time, type);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> book = Book(<span class="string">'Javascript'</span>, <span class="string">'2015'</span>, <span class="string">'js'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(book);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> SuperClass = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.superValue = <span class="literal">true</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 为父类添加公有方法</span></span><br><span class="line">SuperClass.prototype.getSuperValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.superValue;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> SubClass = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.subValue = <span class="literal">false</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承父类</span></span><br><span class="line">SubClass.prototype = <span class="keyword">new</span> SuperClass();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 为子类添加公有方法</span></span><br><span class="line">SubClass.prototype.getSubValue = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.subValue;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> SubClass();</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'a.getSuperValue() ='</span>, a.getSuperValue()); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'a.getSubValue() ='</span>, a.getSubValue()); <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'a.superValue ='</span>, a.superValue); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'a.subValue ='</span>, a.subValue); <span class="comment">// false</span></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'a instanceof SubClass ='</span>, a <span class="keyword">instanceof</span> SubClass); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'a instanceof SuperClass ='</span>, a <span class="keyword">instanceof</span> SuperClass); <span class="comment">// true</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'SubClass instanceof SuperClass ='</span>, SubClass <span class="keyword">instanceof</span> SuperClass); <span class="comment">// false</span></span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'SubClass.prototype instanceof SuperClass ='</span>, SubClass.prototype <span class="keyword">instanceof</span> SuperClass); <span class="comment">// true</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 有缺陷，用new SubClass()创建两个实例时 a, b，这两个实例的属性是同一个，a修改属性superValue，b的superValue会被a修改</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">SuperClass</span>(<span class="params">id</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.books = [<span class="string">'Javascript'</span>, <span class="string">'html'</span>, <span class="string">'css'</span>];</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 值类型公有熟悉</span></span><br><span class="line">  <span class="keyword">this</span>.id = id;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">SuperClass.prototype.showBooks = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="keyword">this</span>.books);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">SubClass</span>(<span class="params">id</span>)</span>&#123;</span><br><span class="line">  <span class="comment">// 继承父类</span></span><br><span class="line">  SuperClass.call(<span class="keyword">this</span>, id);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建第一个子类的实例</span></span><br><span class="line"><span class="keyword">var</span> instance1 = <span class="keyword">new</span> SubClass(<span class="number">10</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建第二个子类的实例</span></span><br><span class="line"><span class="keyword">var</span> instance2 = <span class="keyword">new</span> SubClass(<span class="number">11</span>);</span><br><span class="line"></span><br><span class="line">instance1.books.push(<span class="string">'设计模式'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(instance1);</span><br><span class="line"><span class="built_in">console</span>.log(instance2);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 有缺陷 - 父类的原型方法不会被子类继承，只是由于父类中是给this绑定属性的，所以子类自然就继承了父类的共有属性，也可以说把父类的属性复制给子类</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明父类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">SuperClass</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.name = name;</span><br><span class="line">  <span class="keyword">this</span>.books = [<span class="string">'Javascript'</span>, <span class="string">'html'</span>, <span class="string">'css'</span>];</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 父类原型公有方法</span></span><br><span class="line">SuperClass.prototype.showName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.name;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 声明子类</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">SubClass</span>(<span class="params">name, time</span>) </span>&#123;</span><br><span class="line">  SuperClass.call(<span class="keyword">this</span>, name);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.time = time;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 类式继承</span></span><br><span class="line">SubClass.prototype = <span class="keyword">new</span> SuperClass();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 子类原型方法</span></span><br><span class="line">SubClass.prototype.getTime = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.time;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> SubClass(<span class="string">'Javascript'</span>, <span class="string">'2015'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(a)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 有缺陷 - 父类构造函数调用两遍</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 原型式继承</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritObject</span>(<span class="params">o</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 声明一个过渡函数</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 过渡对象的原型继承父对象</span></span><br><span class="line">  F.prototype = o;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 返回过渡对象的一个实例，该实例的原型继承了父对象</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> F();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 寄生式继承 继承原型</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 传递参数 subClass 子类</span></span><br><span class="line"><span class="comment"> * 传递参数 superClass 父类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritPrototype</span>(<span class="params">subClass, superClass</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> p = <span class="keyword">new</span> inheritObject(superClass.prototype);</span><br><span class="line"></span><br><span class="line">  p.constructor = subClass;</span><br><span class="line"></span><br><span class="line">  subClass.prototype = p;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义父类</span></span><br><span class="line"><span class="keyword">var</span> SuperClass = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.name = name;</span><br><span class="line">  <span class="keyword">this</span>.colors = [<span class="string">'red'</span>, <span class="string">'green'</span>, <span class="string">'yellow'</span>];</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义父类原型方法</span></span><br><span class="line">SuperClass.prototype.getName = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="keyword">this</span>.name);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义子类</span></span><br><span class="line"><span class="keyword">var</span> SubClass = <span class="function"><span class="keyword">function</span>(<span class="params">name, time</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 构造函数式继承</span></span><br><span class="line">  SuperClass.call(<span class="keyword">this</span>, name);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 子类新增属性</span></span><br><span class="line">  <span class="keyword">this</span>.time = time;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 寄生式继承父类原型</span></span><br><span class="line">inheritPrototype(SubClass, SuperClass);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 子类新增原型方法</span></span><br><span class="line">SubClass.prototype.getTime = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="keyword">this</span>.time);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> SubClass(<span class="string">'javascript'</span>, <span class="string">'2015'</span>);</span><br><span class="line"><span class="keyword">var</span> b = <span class="keyword">new</span> SubClass(<span class="string">'Nodejs'</span>, <span class="string">'2015'</span>);</span><br><span class="line"></span><br><span class="line">a.getName();</span><br></pre></td></tr></table></figure>

<h2 id="第三章"><a href="#第三章" class="headerlink" title="第三章"></a>第三章</h2><p>简单工厂模式</p>
<ul>
<li>1.js - 简单工厂模式</li>
<li>2.js - 简单工厂模式2</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 篮球基类</span></span><br><span class="line"><span class="keyword">var</span> BasketBall = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.intro = <span class="string">'篮球盛行于美国'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">BasketBall.prototype = &#123;</span><br><span class="line">  getMember: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'每个队伍需要5名队员'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  getBallSize: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'篮球很大'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 足球基类</span></span><br><span class="line"><span class="keyword">var</span> FootBall = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.intro = <span class="string">'足球在世界范围内很流行'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">FootBall.prototype = &#123;</span><br><span class="line">  getMember: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'每个队伍需要11名队员'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  getBallSize: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'足球很大'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 网球基类</span></span><br><span class="line"><span class="keyword">var</span> Tennis = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.intro = <span class="string">'每年有很多网球系列赛'</span>;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">Tennis.prototype = &#123;</span><br><span class="line">  getMember: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'每个队伍需要1名队员'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  getBallSize: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'网球很小'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 运动工厂</span></span><br><span class="line"><span class="keyword">var</span> SportsFactory = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">switch</span>(name) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'NBA'</span>:</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> BasketBall();</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'wordCup'</span>:</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> FootBall();</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'FrenchOpen'</span>:</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">new</span> Tennis();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 为NBA杯创建一个篮球，只需要记住运动工厂 SportsFactory，调用并创建</span></span><br><span class="line"><span class="keyword">var</span> NBA = SportsFactory(<span class="string">'NBA'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(NBA);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">createBook</span>(<span class="params">name, time, type</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> o = &#123;</span><br><span class="line">    name: name,</span><br><span class="line">    time: time,</span><br><span class="line">    type: type,</span><br><span class="line">    getName: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>.name;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> o;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> book1 = createBook(<span class="string">'javascript'</span>, <span class="string">'2015'</span>, <span class="string">'js'</span>);</span><br><span class="line"><span class="keyword">var</span> book2 = createBook(<span class="string">'Nodejs'</span>, <span class="string">'2015'</span>, <span class="string">'Nodejs'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(book2);</span><br></pre></td></tr></table></figure>

<h2 id="第四章"><a href="#第四章" class="headerlink" title="第四章"></a>第四章</h2><p>工厂方法模式</p>
<ul>
<li>1.js - 工厂方法模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"><span class="keyword">var</span> Factory = <span class="function"><span class="keyword">function</span>(<span class="params">type, text</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">this</span> <span class="keyword">instanceof</span> Factory) &#123;</span><br><span class="line">    <span class="keyword">this</span>[type](text);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Factory(type, text);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">Factory.prototype = &#123;</span><br><span class="line">  javascript: <span class="function"><span class="keyword">function</span>(<span class="params">text</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(text + <span class="string">'javascript'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  nodejs: <span class="function"><span class="keyword">function</span>(<span class="params">text</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(text + <span class="string">'nodejs'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">Factory(<span class="string">'javascript'</span>, <span class="string">'万能的'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 好处是增加基类时，不需要在修改 Factory 了</span></span><br></pre></td></tr></table></figure>

<h2 id="第五章"><a href="#第五章" class="headerlink" title="第五章"></a>第五章</h2><p>抽象工厂模式</p>
<ul>
<li>1.js - 抽象工厂模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> VehicleFactory = <span class="function"><span class="keyword">function</span>(<span class="params">subClass, superType</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 判断抽象工厂中是否有该抽象类</span></span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">typeof</span> VehicleFactory[superType] === <span class="string">'function'</span>) &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 缓存类</span></span><br><span class="line">    <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 继承父类属性和方法</span></span><br><span class="line">    F.prototype = <span class="keyword">new</span> VehicleFactory[superType]();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 将子类constructor指向子类</span></span><br><span class="line">    F.constructor = subClass;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 子类原型继承”父类“</span></span><br><span class="line">    subClass.prototype = <span class="keyword">new</span> F();</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'未创建该抽象类'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 小汽车抽象类</span></span><br><span class="line">VehicleFactory.Car = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.type = <span class="string">'car'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">VehicleFactory.Car.prototype = &#123;</span><br><span class="line">  getPrice: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'抽象方法不能调用'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  getSpeed: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'抽象方法不能调用'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 公交车抽象类</span></span><br><span class="line">VehicleFactory.Bus = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.type = <span class="string">'bus'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">VehicleFactory.Bus.prototype = &#123;</span><br><span class="line">  getPrice: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'抽象方法不能调用'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  getSpeed: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'抽象方法不能调用'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 货车抽象类</span></span><br><span class="line">VehicleFactory.Truck = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.type = <span class="string">'truck'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">VehicleFactory.Truck.prototype = &#123;</span><br><span class="line">  getPrice: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'抽象方法不能调用'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  getSpeed: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'抽象方法不能调用'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 宝马汽车子类</span></span><br><span class="line"><span class="keyword">var</span> BMW = <span class="function"><span class="keyword">function</span>(<span class="params">price, speed</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.price = price;</span><br><span class="line">  <span class="keyword">this</span>.speed = speed;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">VehicleFactory(BMW, <span class="string">'Car'</span>);</span><br><span class="line"></span><br><span class="line">BMW.prototype.getPrice = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.price;</span><br><span class="line">&#125;;</span><br><span class="line">BMW.prototype.getSpeed = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.speed;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> BMW(<span class="number">100</span>, <span class="number">2</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(a.getPrice());</span><br><span class="line"><span class="built_in">console</span>.log(a.type);</span><br></pre></td></tr></table></figure>

<h2 id="第六章"><a href="#第六章" class="headerlink" title="第六章"></a>第六章</h2><p>建造者模式</p>
<ul>
<li>1.js - 建造者模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Human = <span class="function"><span class="keyword">function</span>(<span class="params">param</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 技能</span></span><br><span class="line">  <span class="keyword">this</span>.skill = param &amp;&amp; param.skill || <span class="string">'保密'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 兴趣爱好</span></span><br><span class="line">  <span class="keyword">this</span>.hobby = param &amp;&amp; param.hobby || <span class="string">'保密'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">Human.prototype = &#123;</span><br><span class="line">  getSkill: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.skill;</span><br><span class="line">  &#125;,</span><br><span class="line">  getHobby: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.hobby;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实例化姓名类</span></span><br><span class="line"><span class="keyword">var</span> Named = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> that = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 构造器</span></span><br><span class="line">  <span class="comment">// 构造函数解析姓名的姓与名</span></span><br><span class="line">  (<span class="function"><span class="keyword">function</span>(<span class="params">name, that</span>) </span>&#123;</span><br><span class="line">    that.wholeName = name;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (name.indexOf(<span class="string">' '</span>) &gt; <span class="number">-1</span>) &#123;</span><br><span class="line">      that.firstName = name.slice(<span class="number">0</span>, name.indexOf(<span class="string">' '</span>));</span><br><span class="line">      that.secondName = name.slice(name.indexOf(<span class="string">' '</span>));</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)(name, that)</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 实例化职位类</span></span><br><span class="line"><span class="keyword">var</span> Work = <span class="function"><span class="keyword">function</span>(<span class="params">work</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> that = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 构造器</span></span><br><span class="line">  <span class="comment">// 构造函数中通过传入的职位特征来设置相应职位以及描述</span></span><br><span class="line">  (<span class="function"><span class="keyword">function</span>(<span class="params">work, that</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">switch</span>(work) &#123;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">'code'</span>:</span><br><span class="line">        that.work = <span class="string">'工程师'</span>;</span><br><span class="line">        that.workDescript = <span class="string">'每天沉醉于编程'</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">'UI'</span>:</span><br><span class="line">      <span class="keyword">case</span> <span class="string">'UE'</span>:</span><br><span class="line">        that.work = <span class="string">'设计师'</span>;</span><br><span class="line">        that.workDescript = <span class="string">'设计更似一种艺术'</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">case</span> <span class="string">'teach'</span>:</span><br><span class="line">        that.work = <span class="string">'教师'</span>;</span><br><span class="line">        that.workDescript = <span class="string">'分享也是一种快乐'</span>;</span><br><span class="line">        <span class="keyword">break</span>;</span><br><span class="line">      <span class="keyword">default</span>:</span><br><span class="line">        that.work = work;</span><br><span class="line">        that.workDescript = <span class="string">'对不起，我们还不清楚您所选择职位的相关描述'</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)(work, that);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 更换期望的职位</span></span><br><span class="line">Work.prototype.changeWork = <span class="function"><span class="keyword">function</span>(<span class="params">work</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.work = work;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加对职位的描述</span></span><br><span class="line">Work.prototype.changeDescript = <span class="function"><span class="keyword">function</span>(<span class="params">des</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.workDescript = des;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 应聘者建造者</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param </span>name 姓名（全名）</span></span><br><span class="line"><span class="comment"> * <span class="doctag">@param </span>work 期望职位</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Person = <span class="function"><span class="keyword">function</span>(<span class="params">name, work</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 创建应聘者缓存对象</span></span><br><span class="line">  <span class="keyword">var</span> _person = <span class="keyword">new</span> Human();</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建应聘者姓名解析对象</span></span><br><span class="line">  _person.name = <span class="keyword">new</span> Named(name);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建应聘者期望职位</span></span><br><span class="line">  _person.work = <span class="keyword">new</span> Work(work);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> _person;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> person = <span class="keyword">new</span> Person(<span class="string">'xiao ming'</span>, <span class="string">'code'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(person)</span><br></pre></td></tr></table></figure>


<h2 id="第七章"><a href="#第七章" class="headerlink" title="第七章"></a>第七章</h2><p>原型模式</p>
<ul>
<li>1.js - 原型模式</li>
<li>2.js - 原型继承</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 图片轮播类</span></span><br><span class="line"><span class="keyword">var</span> LoopImages = <span class="function"><span class="keyword">function</span>(<span class="params">imgArr, container</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.imagesArray = imgArr; <span class="comment">// 轮播图片组</span></span><br><span class="line">  <span class="keyword">this</span>.container = container; <span class="comment">// 轮播图片容器</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">LoopImages.prototype = &#123;</span><br><span class="line">  <span class="comment">// 创建轮播图片</span></span><br><span class="line">  createImages: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'LoopImages createImage function'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 切换下一张图片</span></span><br><span class="line">  changeImage: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'LoopImages changeImage function'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 上下滑动切换类</span></span><br><span class="line"><span class="keyword">var</span> SlideLoopImg = <span class="function"><span class="keyword">function</span>(<span class="params">imgArr, container</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 构造函数继承图片轮播类</span></span><br><span class="line">  LoopImages.call(<span class="keyword">this</span>, imgArr, container);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">SlideLoopImg.prototype = <span class="keyword">new</span> LoopImages();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 重写继承的切换下一张方法</span></span><br><span class="line">SlideLoopImg.prototype.changeImage = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'SlideLoopImg changeImage function'</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 渐隐切换类</span></span><br><span class="line"><span class="keyword">var</span> FadeLoopImg = <span class="function"><span class="keyword">function</span>(<span class="params">imgArr, container, arrow</span>) </span>&#123;</span><br><span class="line">  LoopImages.call(<span class="keyword">this</span>, imgArr, container);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 切换剪头私有变量</span></span><br><span class="line">  <span class="keyword">this</span>.arrow = arrow;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">FadeLoopImg.prototype = <span class="keyword">new</span> LoopImages();</span><br><span class="line">FadeLoopImg.prototype.changeImage = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'FadeLoopImg changeImage function'</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试用例</span></span><br><span class="line"><span class="keyword">var</span> fadeImg = <span class="keyword">new</span> FadeLoopImg([<span class="string">'a.png'</span>, <span class="string">'b.png'</span>], <span class="string">'slider'</span>, <span class="string">'123'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(fadeImg);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/**</span></span><br><span class="line"><span class="comment"> * 基于已经存在的模板对象克隆出新对象的模式</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 参数1，参数2，参数3...表示模板对象</span></span><br><span class="line"><span class="comment"> * 注意。这里对模板引用类型的属性实质上进行了浅复制（引用类型属性共享），可以根据需求自行深复制（引用类型属性复制）</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">prototypeExtend</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 缓存类</span></span><br><span class="line">  <span class="keyword">var</span> F = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="built_in">arguments</span>.length; i++) &#123;</span><br><span class="line">    <span class="comment">// 遍历每个末班对象中的属性</span></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> j <span class="keyword">in</span> <span class="built_in">arguments</span>[i]) &#123;</span><br><span class="line">      <span class="comment">// 将属性复制到缓存类原型中</span></span><br><span class="line">      F.prototype[j] = <span class="built_in">arguments</span>[i][j];</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 返回缓存类的一个实例</span></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> F();</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> penguin = prototypeExtend(&#123;</span><br><span class="line">  speed: <span class="number">20</span>,</span><br><span class="line">  swim: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'游泳速度'</span>+ <span class="keyword">this</span>.speed);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;,&#123;</span><br><span class="line">  run: <span class="function"><span class="keyword">function</span>(<span class="params">speed</span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'奔跑速度'</span>+ speed)</span><br><span class="line">  &#125;</span><br><span class="line">&#125;, &#123;</span><br><span class="line">  jump: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'跳跃动作'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">penguin.swim();</span><br><span class="line">penguin.run(<span class="number">10</span>);</span><br><span class="line">penguin.jump();</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(penguin.__proto__);</span><br></pre></td></tr></table></figure>

<h2 id="第八章"><a href="#第八章" class="headerlink" title="第八章"></a>第八章</h2><p>单例模式</p>
<ul>
<li>1.js - 单例模式（创建命名空间）</li>
<li>2.js - 静态变量（无法修改的静态变量）</li>
<li>3.js - 惰性单例（有时候对于单例对象需要延迟创建，所以在单例中还存在一种延迟创建的形式，有人也称之为‘惰性创建’）</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> A = &#123;</span><br><span class="line">  Util: &#123;</span><br><span class="line">    util_method1: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;,</span><br><span class="line">    util_method2: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  Tool: &#123;</span><br><span class="line">    tool_method1: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;,</span><br><span class="line">    tool_method2: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  Ajax: &#123;</span><br><span class="line">    <span class="keyword">get</span>: function() &#123;&#125;,</span><br><span class="line">    post: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  others: &#123;</span><br><span class="line">    <span class="comment">// ...</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.Util.util_method2();</span><br><span class="line">A.Tool.tool_method1();</span><br><span class="line">A.Ajax.get();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Config = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 私有变量</span></span><br><span class="line">  <span class="keyword">var</span> config = &#123;</span><br><span class="line">    MAX_NUM: <span class="number">100</span>,</span><br><span class="line">    MIN_NUM: <span class="number">1</span>,</span><br><span class="line">    COUNT: <span class="number">1000</span></span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 返回取值器对象</span></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">// 取值器方法</span></span><br><span class="line">    <span class="keyword">get</span>: function(name) &#123;</span><br><span class="line">      <span class="keyword">return</span> config[name] ? config[name] : <span class="literal">null</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> count = Config.get(<span class="string">'COUNT'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(count);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 惰性载入单例</span></span><br><span class="line"><span class="keyword">var</span> LazySingle = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 单例实例引用</span></span><br><span class="line">  <span class="keyword">var</span> _instance = <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 单例</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">Single</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 这里定义私有属性和方法</span></span><br><span class="line">    <span class="keyword">return</span> &#123;</span><br><span class="line">      publicMethod: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;,</span><br><span class="line">      publicProperty: <span class="string">'1.0'</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (!_instance) &#123;</span><br><span class="line">      _instance = Single();</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 返回单例</span></span><br><span class="line">    <span class="keyword">return</span> _instance;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( LazySingle().publicProperty ); <span class="comment">// 1.0</span></span><br><span class="line"><span class="built_in">console</span>.log( LazySingle() === LazySingle() ); <span class="comment">// true</span></span><br></pre></td></tr></table></figure>

<h2 id="第九章"><a href="#第九章" class="headerlink" title="第九章"></a>第九章</h2><p>外观模式</p>
<p>为一组复杂的子系统接口提供一个更高级的统一接口，通过这个接口使得对子系统接口的访问更容易。</p>
<p>在javascript中有时也会用于底层结构兼容性做统一封装来简化用户使用</p>
<ul>
<li>1.js - 外观模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 外观模式可以简化底层接口复杂性，也可以解决浏览器兼容性问题</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 外观模式实现</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">addEvent</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (dom.addEventListener) &#123;</span><br><span class="line">    dom.addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (dom.attachEvent) &#123;</span><br><span class="line">    dom.attachEvent(<span class="string">'on'</span> + type, fn);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    dom[<span class="string">'on'</span> + type] = fn;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> myInput = <span class="built_in">document</span>.getElementById(<span class="string">'myinput'</span>);</span><br><span class="line"></span><br><span class="line">addEvent(myInput, <span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'绑定第一个事件'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">addEvent(myInput, <span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'绑定第二个事件'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="第十章"><a href="#第十章" class="headerlink" title="第十章"></a>第十章</h2><p>适配器模式</p>
<p>将一个类（对象）的接口（方法或属性）转化成另外一个接口，以满足用户需求。</p>
<p>类（对象）之间接口的不兼容问题可以通过适配器模式解决</p>
<ul>
<li>1.js - 适配器模式</li>
<li>2.js - 参数适配器</li>
<li>3.js - 数据适配器</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 定义框架</span></span><br><span class="line"><span class="keyword">var</span> A = A || &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过id获取元素</span></span><br><span class="line">A.g = <span class="function"><span class="keyword">function</span>(<span class="params">id</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">document</span>.getElementById(id);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 为元素绑定事件</span></span><br><span class="line">A.on = <span class="function"><span class="keyword">function</span>(<span class="params">id, type, fn</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 如果传递参数是字符串则以id处理，否则以元素对象处理</span></span><br><span class="line">  <span class="keyword">var</span> dom = <span class="keyword">typeof</span> id ===<span class="string">'string'</span> ? <span class="keyword">this</span>.g(id) : id;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (dom.addEventListener) &#123;</span><br><span class="line">    dom.addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (dom.attachEvent) &#123;</span><br><span class="line">    dom.attachEvent(<span class="string">'on'</span> + type, fn);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    dom[<span class="string">'on'</span> + type] = fn;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.on(<span class="built_in">window</span>, <span class="string">'load'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 按钮点击事件</span></span><br><span class="line">  A.on(<span class="string">'mybutton'</span>, <span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// xxx</span></span><br><span class="line">  &#125;);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：忽然项目中想把依赖换成jQuery，但总不能所有的方法都用jQuery的语法重新写一遍，那就写个适配器吧~</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/********* 适配器（适配jQuery） *************/</span></span><br><span class="line"></span><br><span class="line">A.g = <span class="function"><span class="keyword">function</span>(<span class="params">id</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 通过jQuery获取jQuery对象，然后返回第一个成员</span></span><br><span class="line">  <span class="keyword">return</span> $(id).get(<span class="number">0</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.on = <span class="function"><span class="keyword">function</span>(<span class="params">id, type, fn</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 如果传递参数是字符串则以id处理，否则以元素对象处理</span></span><br><span class="line">  <span class="keyword">var</span> dom = <span class="keyword">typeof</span> id === <span class="string">'string'</span> ? $(<span class="string">'#'</span> + id) : $(id);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 绑定事件</span></span><br><span class="line">  dom.on(type, fn);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：如果方法需要传入很多参数，那么记住这些参数的顺序是很难的，所以我们经常是以一个参数对象方式传入的。</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params">name, title, age, color, size, prize</span>) </span>&#123;&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * obj.name: name</span></span><br><span class="line"><span class="comment"> * obj.title: title</span></span><br><span class="line"><span class="comment"> * obj.age: age</span></span><br><span class="line"><span class="comment"> * obj.color: color</span></span><br><span class="line"><span class="comment"> * obj.size: size</span></span><br><span class="line"><span class="comment"> * obj.prize: prize</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params">obj</span>) </span>&#123;&#125;</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 但是调用它的时候不知道传递的参数是否完整，此时我们通常的做法是用适配器来适配传入的参数对象</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">a</span>(<span class="params">obj</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> _default = &#123;</span><br><span class="line">    name: <span class="string">'雨夜清荷'</span>,</span><br><span class="line">    title: <span class="string">'设计模式'</span>,</span><br><span class="line">    age: <span class="string">'20'</span>,</span><br><span class="line">    color: <span class="string">'pink'</span>,</span><br><span class="line">    size: <span class="number">100</span>,</span><br><span class="line">    prize: <span class="number">50</span></span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    _default[i] = obj[i] || _default[i];</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// code ....</span></span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">arrToObj</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    name: arr[<span class="number">0</span>],</span><br><span class="line">    type: arr[<span class="number">1</span>],</span><br><span class="line">    title: arr[<span class="number">2</span>],</span><br><span class="line">    data: arr[<span class="number">3</span>]</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> arr = [<span class="string">'javascript'</span>, <span class="string">'book'</span>, <span class="string">'前端编程语言'</span>, <span class="string">'12月1日'</span>];</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = arrToObj(arr);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(obj);</span><br></pre></td></tr></table></figure>

<h2 id="第十二章"><a href="#第十二章" class="headerlink" title="第十二章"></a>第十二章</h2><p>装饰者模式</p>
<p>在不改变原对象的基础上，通过对其进行封装扩展（添加属性和方法）使原有对象可以满足用户的更复杂的需求。</p>
<p>同样对原有对象进行扩展的还有适配器模式，所不同的是适配器进行扩展很多时候是对对象内部的重组，因此了解其自身结构是必须的。而装饰者对对象的扩展是一种良性扩展，不用了解其具体实现，只是在外部进行了一次封装扩展，这又是对原有功能完整性的一种保护。</p>
<ul>
<li>1.js - 装饰者模式（对原有对象的属性与方法的添加）</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 装饰者</span></span><br><span class="line"><span class="keyword">var</span> decorate = <span class="function"><span class="keyword">function</span>(<span class="params">id, fn</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 获取事件源</span></span><br><span class="line">  <span class="keyword">var</span> dom = <span class="built_in">document</span>.getElementById(id);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 若事件源已绑定事件</span></span><br><span class="line">  <span class="keyword">if</span> (<span class="keyword">typeof</span> dom.onclick === <span class="string">'function'</span>) &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 缓存事件源原有事件</span></span><br><span class="line">    <span class="keyword">var</span> oldClickFn = dom.onclick;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 为事件源定义新的事件</span></span><br><span class="line">    dom.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 事件源原有回调函数</span></span><br><span class="line">      oldClickFn();</span><br><span class="line">      <span class="comment">// 执行事件源新增回调函数</span></span><br><span class="line">      fn();</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 如果未绑定事件，直接为事件源添加事件</span></span><br><span class="line">    dom.onclick = fn;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 电话输入框功能装饰</span></span><br><span class="line">decorate(<span class="string">'tel_input'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">document</span>.getElementById(<span class="string">'tel_demo_text'</span>).style.display = <span class="string">'none'</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 与适配器模式的区别：</span></span><br><span class="line"><span class="comment">// 适配器方法使对原有对象适配，添加的方法与原有方法功能上大致相似。但是装饰者提供的方法与原来的方法功能项是有一定区别的。</span></span><br><span class="line"><span class="comment">// 在装饰者模式中，不需要了解对象原有的功能，而且对象原有的方法照样可以原封不动的使用</span></span><br><span class="line"><span class="comment">// 在适配器中增加的方法要调用原有的方法，需要了解原有方法实现的具体细节，而在装饰者中原封不动的使用，不需要知道原有方法实现的具体细节。</span></span><br></pre></td></tr></table></figure>

<h2 id="第十三章"><a href="#第十三章" class="headerlink" title="第十三章"></a>第十三章</h2><p>桥接模式（Bridge）</p>
<p>在系统沿着多个维度变化的同时，又不增加其复杂度并已达到解耦</p>
<ul>
<li>1.js - 桥接模式（简单）</li>
<li>2.js - 桥接模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> spans = <span class="built_in">document</span>.getElementsByTagName(<span class="string">'span'</span>);</span><br><span class="line"></span><br><span class="line">spans[<span class="number">0</span>].onmouseover = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.style.color = <span class="string">'red'</span>;</span><br><span class="line">  <span class="keyword">this</span>.style.background = <span class="string">'#ddd'</span>;</span><br><span class="line">&#125;;</span><br><span class="line">spans[<span class="number">0</span>].onmouseout = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.style.color = <span class="string">'#333'</span>;</span><br><span class="line">  <span class="keyword">this</span>.style.background = <span class="string">'#f5f5f5'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">spans[<span class="number">1</span>].onmouseover = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.getElementsByTagName(<span class="string">'strong'</span>)[<span class="number">0</span>].style.color = <span class="string">'red'</span>;</span><br><span class="line">  <span class="keyword">this</span>.getElementsByTagName(<span class="string">'strong'</span>)[<span class="number">0</span>].style.background = <span class="string">'#ddd'</span>;</span><br><span class="line">&#125;;</span><br><span class="line">spans[<span class="number">1</span>].onmouseout = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.getElementsByTagName(<span class="string">'strong'</span>)[<span class="number">0</span>].style.color = <span class="string">'#333'</span>;</span><br><span class="line">  <span class="keyword">this</span>.getElementsByTagName(<span class="string">'strong'</span>)[<span class="number">0</span>].style.background = <span class="string">'#f5f5f5'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用桥接模式后</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">changeColor</span>(<span class="params">dom, color, bg</span>) </span>&#123;</span><br><span class="line">  dom.style.color = color;</span><br><span class="line">  <span class="keyword">this</span>.style.background = bg;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 事件与业务逻辑的桥梁</span></span><br><span class="line">spans[<span class="number">0</span>].onmouseover = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  changeColor(<span class="keyword">this</span>, <span class="string">'red'</span>, <span class="string">'#ddd'</span>);</span><br><span class="line">&#125;;</span><br><span class="line">spans[<span class="number">0</span>].onmouseout = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  changeColor(<span class="keyword">this</span>, <span class="string">'#333'</span>, <span class="string">'#f5f5f5'</span>);</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 多维变量类</span></span><br><span class="line"><span class="comment">// 运动单元</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Speed</span>(<span class="params">x, y</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.x = x;</span><br><span class="line">  <span class="keyword">this</span>.y = y;</span><br><span class="line">&#125;</span><br><span class="line">Speed.prototype.run = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'跑起来'</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 着色单元</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Color</span>(<span class="params">cl</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.color = cl;</span><br><span class="line">&#125;</span><br><span class="line">Color.prototype.draw = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'绘制色彩'</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Ball</span>(<span class="params">x, y, c</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 实现运动单元</span></span><br><span class="line">  <span class="keyword">this</span>.speed = <span class="keyword">new</span> Speed(x, y);</span><br><span class="line">  <span class="comment">// 实现着色单元</span></span><br><span class="line">  <span class="keyword">this</span>.color = <span class="keyword">new</span> Color(c);</span><br><span class="line">&#125;;</span><br><span class="line">Ball.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 实现运动</span></span><br><span class="line">  <span class="keyword">this</span>.speed.run();</span><br><span class="line">  <span class="comment">// 实现着色</span></span><br><span class="line">  <span class="keyword">this</span>.color.draw();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = <span class="keyword">new</span> Ball(<span class="number">1</span>,<span class="number">2</span>,<span class="string">'red'</span>);</span><br><span class="line">a.init();</span><br></pre></td></tr></table></figure>

<h2 id="第十四章"><a href="#第十四章" class="headerlink" title="第十四章"></a>第十四章</h2><p>组合模式（Composite）</p>
<p>又称部分-整体模式，将对象整合成树形结构以表示“部分整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性</p>
<ul>
<li>1.js - 组合模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br><span class="line">204</span><br><span class="line">205</span><br><span class="line">206</span><br><span class="line">207</span><br><span class="line">208</span><br><span class="line">209</span><br><span class="line">210</span><br><span class="line">211</span><br><span class="line">212</span><br><span class="line">213</span><br><span class="line">214</span><br><span class="line">215</span><br><span class="line">216</span><br><span class="line">217</span><br><span class="line">218</span><br><span class="line">219</span><br><span class="line">220</span><br><span class="line">221</span><br><span class="line">222</span><br><span class="line">223</span><br><span class="line">224</span><br><span class="line">225</span><br><span class="line">226</span><br><span class="line">227</span><br><span class="line">228</span><br><span class="line">229</span><br><span class="line">230</span><br><span class="line">231</span><br><span class="line">232</span><br><span class="line">233</span><br><span class="line">234</span><br><span class="line">235</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：经理准备在用户首页添加一个新闻模块，当然新闻的内容是根据用户平时关注的内容挖掘的，因此有的人可能会显示文字新闻，有的人会显示图片新闻，甚至有的人显示的新闻是一个直播链接，方便用户观看比赛。。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 寄生式继承</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">inheritPrototype</span>(<span class="params">subClass, superClass</span>) </span>&#123;</span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">F</span>(<span class="params"></span>) </span>&#123;&#125;</span><br><span class="line">  F.prototype = superClass.prototype;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> p = <span class="keyword">new</span> F();</span><br><span class="line">  p.constructor = subClass;</span><br><span class="line"></span><br><span class="line">  subClass.prototype = p;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 虚拟类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> News = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 子组件容器</span></span><br><span class="line">  <span class="keyword">this</span>.children = [];</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 当前组件元素</span></span><br><span class="line">  <span class="keyword">this</span>.element = <span class="literal">null</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">News.prototype = &#123;</span><br><span class="line">  init: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'请重写你的方法'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  add: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'请重写你的方法'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  getElement: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">throw</span> <span class="keyword">new</span> <span class="built_in">Error</span>(<span class="string">'请重写你的方法'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 容器类构造函数</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Container = <span class="function"><span class="keyword">function</span>(<span class="params">id, parent</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 构造函数继承类</span></span><br><span class="line">  News.call(<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 模块ID</span></span><br><span class="line">  <span class="keyword">this</span>.id = id;</span><br><span class="line">  <span class="comment">// 模块的父容器</span></span><br><span class="line">  <span class="keyword">this</span>.parent = parent;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 构建方法</span></span><br><span class="line">  <span class="keyword">this</span>.init();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">inheritPrototype(Container, News);</span><br><span class="line"></span><br><span class="line">Container.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.element = <span class="built_in">document</span>.createElement(<span class="string">'ul'</span>);</span><br><span class="line">  <span class="keyword">this</span>.element.id = <span class="keyword">this</span>.id;</span><br><span class="line">  <span class="keyword">this</span>.element.className = <span class="string">'new-container'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">Container.prototype.add = <span class="function"><span class="keyword">function</span>(<span class="params">child</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 在子元素容器中插入子元素</span></span><br><span class="line">  <span class="keyword">this</span>.children.push(child);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 插入当前组件元素树中</span></span><br><span class="line">  <span class="keyword">this</span>.element.appendChild(child.getElement());</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取当前元素方法</span></span><br><span class="line">Container.prototype.getElement = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.element;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 显示方法</span></span><br><span class="line">Container.prototype.show = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.parent.appendChild(<span class="keyword">this</span>.element);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 子类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Item = <span class="function"><span class="keyword">function</span>(<span class="params">classname</span>) </span>&#123;</span><br><span class="line">  News.call(<span class="keyword">this</span>);</span><br><span class="line">  <span class="keyword">this</span>.classname = classname || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.init();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">inheritPrototype(Item, News);</span><br><span class="line"></span><br><span class="line">Item.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.element = <span class="built_in">document</span>.createElement(<span class="string">'li'</span>);</span><br><span class="line">  <span class="keyword">this</span>.element.className = <span class="keyword">this</span>.classname;</span><br><span class="line">&#125;;</span><br><span class="line">Item.prototype.add = <span class="function"><span class="keyword">function</span>(<span class="params">child</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.children.push(child);</span><br><span class="line">  <span class="keyword">this</span>.element.appendChild(child.getElement());</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">&#125;;</span><br><span class="line">Item.prototype.getElement = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.element;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 新闻组类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> NewsGroup = <span class="function"><span class="keyword">function</span>(<span class="params">classname</span>) </span>&#123;</span><br><span class="line">  News.call(<span class="keyword">this</span>);</span><br><span class="line">  <span class="keyword">this</span>.className = classname || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.init();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">inheritPrototype(NewsGroup, News);</span><br><span class="line"></span><br><span class="line">NewsGroup.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.element = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>);</span><br><span class="line">  <span class="keyword">this</span>.element.className = <span class="keyword">this</span>.classname;</span><br><span class="line">&#125;;</span><br><span class="line">NewsGroup.prototype.add = <span class="function"><span class="keyword">function</span>(<span class="params">child</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.children.push(child);</span><br><span class="line">  <span class="keyword">this</span>.element.appendChild(child.getElement());</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">&#125;;</span><br><span class="line">NewsGroup.prototype.getElement = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.element;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 创建图片新闻类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> ImageNews = <span class="function"><span class="keyword">function</span>(<span class="params">url, href, classname</span>) </span>&#123;</span><br><span class="line">  News.call(<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.url = url || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.href = href || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.classname = classname || <span class="string">'normal'</span>;</span><br><span class="line">  <span class="keyword">this</span>.init();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">inheritPrototype(ImageNews, News);</span><br><span class="line"></span><br><span class="line">ImageNews.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.element = <span class="built_in">document</span>.createElement(<span class="string">'a'</span>);</span><br><span class="line">  <span class="keyword">var</span> img = <span class="keyword">new</span> Image();</span><br><span class="line">  img.src = <span class="keyword">this</span>.url;</span><br><span class="line">  <span class="keyword">this</span>.element.appendChild(img);</span><br><span class="line">  <span class="keyword">this</span>.element.className = <span class="string">'image-news '</span> + <span class="keyword">this</span>.classname;</span><br><span class="line">  <span class="keyword">this</span>.element.href = <span class="keyword">this</span>.href;</span><br><span class="line">&#125;;</span><br><span class="line">ImageNews.prototype.add = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">ImageNews.prototype.getElement = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.element;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 基类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> IconNews = <span class="function"><span class="keyword">function</span>(<span class="params">text, href, type</span>) </span>&#123;</span><br><span class="line">  News.call(<span class="keyword">this</span>);</span><br><span class="line">  <span class="keyword">this</span>.text = text || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.href = href || <span class="string">'#'</span>;</span><br><span class="line">  <span class="keyword">this</span>.type = type || <span class="string">'video'</span>;</span><br><span class="line">  <span class="keyword">this</span>.init();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">inheritPrototype(IconNews, News);</span><br><span class="line"></span><br><span class="line">IconNews.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.element = <span class="built_in">document</span>.createElement(<span class="string">'a'</span>);</span><br><span class="line">  <span class="keyword">this</span>.element.innerHTML = <span class="keyword">this</span>.text;</span><br><span class="line">  <span class="keyword">this</span>.element.href = <span class="keyword">this</span>.href;</span><br><span class="line">  <span class="keyword">this</span>.element.className = <span class="keyword">this</span>.classname;</span><br><span class="line">&#125;;</span><br><span class="line">IconNews.prototype.add = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">IconNews.prototype.getElement = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.element;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 基类</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> EasyNews = <span class="function"><span class="keyword">function</span>(<span class="params">text, href</span>) </span>&#123;</span><br><span class="line">  News.call(<span class="keyword">this</span>);</span><br><span class="line">  <span class="keyword">this</span>.text = text || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.href = href || <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">this</span>.init();</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">inheritPrototype(EasyNews, News);</span><br><span class="line"></span><br><span class="line">EasyNews.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.element = <span class="built_in">document</span>.createElement(<span class="string">'a'</span>);</span><br><span class="line">  <span class="keyword">this</span>.element.innerHTML = <span class="keyword">this</span>.text;</span><br><span class="line">  <span class="keyword">this</span>.element.href = <span class="keyword">this</span>.href;</span><br><span class="line">  <span class="keyword">this</span>.element.className = <span class="string">'text'</span>;</span><br><span class="line">&#125;;</span><br><span class="line">EasyNews.prototype.add = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">EasyNews.prototype.getElement = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>.element;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 创建新闻模块</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> news1 = <span class="keyword">new</span> Container(<span class="string">'news'</span>, <span class="built_in">document</span>.body);</span><br><span class="line">news1.add(</span><br><span class="line">  <span class="keyword">new</span> Item(<span class="string">'normal'</span>).add(</span><br><span class="line">    <span class="keyword">new</span> IconNews(<span class="string">'哈哈哈'</span>, <span class="string">'#'</span>, <span class="string">'video'</span>)</span><br><span class="line">  )</span><br><span class="line">).add(</span><br><span class="line">  <span class="keyword">new</span> Item(<span class="string">'normal'</span>).add(</span><br><span class="line">    <span class="keyword">new</span> IconNews(<span class="string">'呵呵呵'</span>, <span class="string">'#'</span>, <span class="string">'live'</span>)</span><br><span class="line">  )</span><br><span class="line">).add(</span><br><span class="line">  <span class="keyword">new</span> Item(<span class="string">'normal'</span>).add(</span><br><span class="line">    <span class="keyword">new</span> NewsGroup(<span class="string">'has-img'</span>).add(</span><br><span class="line">      <span class="keyword">new</span> ImageNews(<span class="string">'img/1.jpg'</span>, <span class="string">'#'</span>, <span class="string">'small'</span>)</span><br><span class="line">    ).add(</span><br><span class="line">      <span class="keyword">new</span> EasyNews(<span class="string">'aaaa'</span>, <span class="string">'#'</span>)</span><br><span class="line">    ).add(</span><br><span class="line">      <span class="keyword">new</span> EasyNews(<span class="string">'五大雷人跑步机'</span>, <span class="string">'#'</span>)</span><br><span class="line">    )</span><br><span class="line">  )</span><br><span class="line">).show();</span><br></pre></td></tr></table></figure>

<h2 id="第十五章"><a href="#第十五章" class="headerlink" title="第十五章"></a>第十五章</h2><p>享元模式（Flyweight），运行共享技术有效地支持大量细粒度的对象，避免对象拥有相同内容造成多余的开销，使大家共享一个类(元类)。</p>
<ul>
<li>1.js - 享元模式</li>
</ul>
<p>根据我自己对享元模式的理解，享元模式的精髓就在于『创建对象的同时，缓存一份对象，日后直接对缓存的对象做操作』</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：分页新闻功能</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 享元对象</span></span><br><span class="line"><span class="keyword">var</span> Flyweight = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 已创建的元素</span></span><br><span class="line">  <span class="keyword">var</span> created = [];</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 创建一个新闻包装容器</span></span><br><span class="line"><span class="comment">   * 根据我自己对享元模式的理解，享元模式的精髓就在于『创建对象的同时，缓存一份对象，日后直接对缓存的对象做操作』</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">create</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> dom = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>);</span><br><span class="line">    <span class="comment">// 讲容器插入新闻列表容器中</span></span><br><span class="line">    <span class="built_in">document</span>.getElementById(<span class="string">'container'</span>).appendChild(dom);</span><br><span class="line">    <span class="comment">// 缓存新创建的元素</span></span><br><span class="line">    created.push(dom);</span><br><span class="line">    <span class="comment">// 返回创建的新元素</span></span><br><span class="line">    <span class="keyword">return</span> dom;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">// 获取创建新闻元素方法</span></span><br><span class="line">    getDiv: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果已创建的元素小于当前页元素总个数，则创建</span></span><br><span class="line">      <span class="keyword">if</span> (created.length &lt; <span class="number">5</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> create();</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 获取第一个元素并插入到最后面</span></span><br><span class="line">        <span class="keyword">var</span> div = created.shift();</span><br><span class="line">        created.push(div);</span><br><span class="line">        <span class="keyword">return</span> div;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 实现需求</span></span><br><span class="line"><span class="keyword">var</span> paper = <span class="number">0</span>;</span><br><span class="line"><span class="keyword">var</span> num = <span class="number">5</span>;</span><br><span class="line"><span class="keyword">var</span> article = [<span class="string">'这是第一条新闻'</span>,<span class="string">'这是第二条新闻'</span>,<span class="string">'这是第三条新闻'</span>,<span class="string">'这是第四条新闻'</span>,<span class="string">'这是第五条新闻'</span>,<span class="string">'这是第六条新闻'</span>];</span><br><span class="line"><span class="keyword">var</span> len = article.length;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加五条新闻</span></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="number">5</span>; i++) &#123;</span><br><span class="line">  <span class="keyword">if</span> (article[i]) &#123;</span><br><span class="line">    <span class="comment">// 通过享元类获取创建的元素并写入新闻内容</span></span><br><span class="line">    Flyweight.getDiv().innerHTML = article[i];</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 下一页</span></span><br><span class="line"><span class="built_in">document</span>.getElementById(<span class="string">'next'</span>).onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 如果新闻内容不足5条则返回</span></span><br><span class="line">  <span class="keyword">if</span>(article.length &lt; <span class="number">5</span>) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> n = ++paper * num % len;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 插入5条新闻</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> j = <span class="number">0</span>; j &lt; <span class="number">5</span>; j++) &#123;</span><br><span class="line">    <span class="comment">// 如果存在第n+j条则插入</span></span><br><span class="line">    <span class="keyword">if</span> (article[n + j]) &#123;</span><br><span class="line">      Flyweight.getDiv().innerHTML = article[n + j];</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span>(article[n + j - len]) &#123;</span><br><span class="line">      <span class="comment">// 否则插入起始位置第n + j - len 条</span></span><br><span class="line">      Flyweight.getDiv().innerHTML = article[n + j - len];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="comment">// 如果都不存在则插入空字符串</span></span><br><span class="line">      Flyweight.getDiv().innerHTML = <span class="string">''</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="第十六章"><a href="#第十六章" class="headerlink" title="第十六章"></a>第十六章</h2><p>模板方法（TemplateMethod）父类中定义一组操作算法骨架，而将一些实现步骤延迟到子类中，使得子类可以不改变一个算法的结构即可重定义该算法的某些实现步骤。</p>
<ul>
<li>1.js - 模板方法模式</li>
<li>2.js - 模板方法模式2</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br><span class="line">158</span><br><span class="line">159</span><br><span class="line">160</span><br><span class="line">161</span><br><span class="line">162</span><br><span class="line">163</span><br><span class="line">164</span><br><span class="line">165</span><br><span class="line">166</span><br><span class="line">167</span><br><span class="line">168</span><br><span class="line">169</span><br><span class="line">170</span><br><span class="line">171</span><br><span class="line">172</span><br><span class="line">173</span><br><span class="line">174</span><br><span class="line">175</span><br><span class="line">176</span><br><span class="line">177</span><br><span class="line">178</span><br><span class="line">179</span><br><span class="line">180</span><br><span class="line">181</span><br><span class="line">182</span><br><span class="line">183</span><br><span class="line">184</span><br><span class="line">185</span><br><span class="line">186</span><br><span class="line">187</span><br><span class="line">188</span><br><span class="line">189</span><br><span class="line">190</span><br><span class="line">191</span><br><span class="line">192</span><br><span class="line">193</span><br><span class="line">194</span><br><span class="line">195</span><br><span class="line">196</span><br><span class="line">197</span><br><span class="line">198</span><br><span class="line">199</span><br><span class="line">200</span><br><span class="line">201</span><br><span class="line">202</span><br><span class="line">203</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 我的理解是，先创建基础类，然后针对基础类做扩展</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：提示框</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 模板类</span></span><br><span class="line"><span class="comment"> * 基础提示框</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @param data 渲染数据</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Alert = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (!data) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 设置内容</span></span><br><span class="line">  <span class="keyword">this</span>.content = data.content;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建提示框面板</span></span><br><span class="line">  <span class="keyword">this</span>.panel = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>);</span><br><span class="line">  <span class="comment">// 创建提示内容组件</span></span><br><span class="line">  <span class="keyword">this</span>.contentNode = <span class="built_in">document</span>.createElement(<span class="string">'p'</span>);</span><br><span class="line">  <span class="comment">// 创建确认按钮组件</span></span><br><span class="line">  <span class="keyword">this</span>.confirmBtn = <span class="built_in">document</span>.createElement(<span class="string">'span'</span>);</span><br><span class="line">  <span class="comment">// 创建关闭按钮组件</span></span><br><span class="line">  <span class="keyword">this</span>.closeBtn = <span class="built_in">document</span>.createElement(<span class="string">'b'</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 为提示框面板添加class</span></span><br><span class="line">  <span class="keyword">this</span>.panel.className = <span class="string">'alert'</span>;</span><br><span class="line">  <span class="comment">// 为确认按钮添加class</span></span><br><span class="line">  <span class="keyword">this</span>.confirmBtn.className = <span class="string">'a-confirm'</span>;</span><br><span class="line">  <span class="comment">// 为关闭按钮添加class</span></span><br><span class="line">  <span class="keyword">this</span>.closeBtn.className = <span class="string">'a-close'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 为确认按钮添加文案</span></span><br><span class="line">  <span class="keyword">this</span>.confirmBtn.innerHTML = data.confirm || <span class="string">'确认'</span>;</span><br><span class="line">  <span class="comment">// 为提示内容添加文本</span></span><br><span class="line">  <span class="keyword">this</span>.contentNode.innerHTML = data.content || <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 点击确认按钮执行方法 如果 data 中有 success 方法则为 success 方法，否则为空函数</span></span><br><span class="line">  <span class="keyword">this</span>.success = data.success || <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">  <span class="comment">// 点击关闭按钮执行方法</span></span><br><span class="line">  <span class="keyword">this</span>.fail = data.fail || <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 提示框原型方法</span></span><br><span class="line">Alert.prototype = &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建方法</span></span><br><span class="line">  init: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 生成提示框</span></span><br><span class="line">    <span class="keyword">this</span>.panel.appendChild(<span class="keyword">this</span>.closeBtn);</span><br><span class="line">    <span class="keyword">this</span>.panel.appendChild(<span class="keyword">this</span>.confirmBtn);</span><br><span class="line">    <span class="keyword">this</span>.panel.appendChild(<span class="keyword">this</span>.contentNode);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 插入页面中</span></span><br><span class="line">    <span class="built_in">document</span>.body.appendChild(<span class="keyword">this</span>.panel);</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 绑定事件</span></span><br><span class="line">    <span class="keyword">this</span>.bindEvent();</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 显示提示框</span></span><br><span class="line">    <span class="keyword">this</span>.show();</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 绑定事件</span></span><br><span class="line">  bindEvent: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>.closeBtn.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 执行取消方法</span></span><br><span class="line">      self.fail();</span><br><span class="line">      <span class="comment">// 隐藏弹层</span></span><br><span class="line">      self.hide();</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">this</span>.confirmBtn.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 执行确认方法</span></span><br><span class="line">      self.success();</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 隐藏弹层</span></span><br><span class="line">      self.hide();</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 隐藏弹窗方法</span></span><br><span class="line">  hide: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.panel.style.display = <span class="string">'none'</span>;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 显示弹层方法</span></span><br><span class="line">  show: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.panel.style.display = <span class="string">'block'</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/* </span></span><br><span class="line"><span class="comment"> * 右侧按钮提示框</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> RightAlert = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 继承基本提示框构造函数</span></span><br><span class="line">  Alert.call(<span class="keyword">this</span>, data);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 为确认按钮添加 right class设置位置居右</span></span><br><span class="line">  <span class="keyword">this</span>.confirmBtn.className = <span class="keyword">this</span>.confirmBtn.className + <span class="string">' right'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承基本提示框方法</span></span><br><span class="line">RightAlert.prototype = <span class="keyword">new</span> Alert();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 标题提示框</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> TitleAlert = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 继承基本提示框构造函数</span></span><br><span class="line">  Alert.call(<span class="keyword">this</span>, data);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 设置标题内容</span></span><br><span class="line">  <span class="keyword">this</span>.title = data.title;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建标题组件</span></span><br><span class="line">  <span class="keyword">this</span>.titleNode = <span class="built_in">document</span>.createElement(<span class="string">'h3'</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 标题组件中写入标题内容</span></span><br><span class="line">  <span class="keyword">this</span>.titleNode.innerHTML = <span class="keyword">this</span>.title;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承原型</span></span><br><span class="line">TitleAlert.prototype = <span class="keyword">new</span> Alert();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 对基本提示框创建方法扩展</span></span><br><span class="line">TitleAlert.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 插入标题</span></span><br><span class="line">  <span class="keyword">this</span>.panel.insertBefore(<span class="keyword">this</span>.titleNode, <span class="keyword">this</span>.panel.firstChild);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 继承基本提示框init方法</span></span><br><span class="line">  Alert.prototype.init.call(<span class="keyword">this</span>);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/***** 继承类也可作为模板类 *****/</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 带有取消按钮的弹出框</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> CancelAlert = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 继承标题提示框构造函数</span></span><br><span class="line">  TitleAlert.call(<span class="keyword">this</span>, data);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 取消按钮文案</span></span><br><span class="line">  <span class="keyword">this</span>.cancel = data.cancel;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建取消按钮</span></span><br><span class="line">  <span class="keyword">this</span>.cancelBtn = <span class="built_in">document</span>.createElement(<span class="string">'span'</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 添加class</span></span><br><span class="line">  <span class="keyword">this</span>.cancelBtn.className = <span class="string">'cancel'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 设置内容</span></span><br><span class="line">  <span class="keyword">this</span>.cancelBtn.innerHTML = <span class="keyword">this</span>.cancel || <span class="string">'取消'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 继承标题提示框原型方法</span></span><br><span class="line">CancelAlert.prototype = <span class="keyword">new</span> Alert();</span><br><span class="line"></span><br><span class="line">CancelAlert.prototype.init = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 继承标题提示框创建方法</span></span><br><span class="line">  TitleAlert.prototype.init.call(<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 由于取消按钮要添加在末尾，所以在创建完其他组建后添加</span></span><br><span class="line">  <span class="keyword">this</span>.panel.appendChild(<span class="keyword">this</span>.cancelBtn);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">CancelAlert.prototype.bindEvent = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">  TitleAlert.prototype.bindEvent.call(<span class="keyword">this</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">this</span>.cancelBtn.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    self.fail();</span><br><span class="line">    self.hide();</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 实例化提示框</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">new</span> CancelAlert(&#123;</span><br><span class="line">  title: <span class="string">'标题提示'</span>,</span><br><span class="line">  content: <span class="string">'提示内容'</span>,</span><br><span class="line">  success: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'ok'</span>);</span><br><span class="line">  &#125;,</span><br><span class="line">  fail: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'cancel'</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;).init();</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">formateString</span>(<span class="params">str, data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> str.replace(<span class="regexp">/\&#123;#(\w+)#\&#125;/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">match, key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">typeof</span> data[key] === <span class="literal">undefined</span> ? <span class="string">''</span> : data[key];</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 基础导航</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Nav = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 基础导航样式模板</span></span><br><span class="line">  <span class="keyword">var</span> item = <span class="string">'&lt;a href="&#123;#href#&#125;" title="&#123;#title#&#125;"&gt;&#123;#name#&#125;&lt;/a&gt;'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 创建字符串</span></span><br><span class="line">  <span class="keyword">var</span> html = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 格式化数据</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.length; i++) &#123;</span><br><span class="line">    html += formateString(item, data[i]);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> html;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 带有消息提醒信息导航</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> NumNav = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> tpl = <span class="string">'&lt;b&gt;&#123;#num#&#125;&lt;/b&gt;'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.length; i++) &#123;</span><br><span class="line">    data[i].name += formateString(tpl, data[i]);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 继承继承类，并返回字符串</span></span><br><span class="line">  <span class="keyword">return</span> Nav.call(<span class="keyword">this</span>, data);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 带有链接地址的导航</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> LinkNav = <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> tpl = <span class="string">'&lt;span&gt;&#123;#link#&#125;&lt;/span&gt;'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.length; i++) &#123;</span><br><span class="line">    data[i].name += formateString(tpl, data[i]);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> Nav.all(<span class="keyword">this</span>, data);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取导航容器</span></span><br><span class="line"><span class="keyword">var</span> nav = <span class="built_in">document</span>.getElementById(<span class="string">'content'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 添加内容</span></span><br><span class="line">nav.innerHTML = NumNav([&#123;</span><br><span class="line">  href: <span class="string">'http://hao.360.cn'</span>,</span><br><span class="line">  title: <span class="string">'360导航'</span>,</span><br><span class="line">  name: <span class="string">'360'</span>,</span><br><span class="line">  num: <span class="string">'10'</span></span><br><span class="line">&#125;,&#123;</span><br><span class="line">  href: <span class="string">'http://www.taobao.com'</span>,</span><br><span class="line">  title: <span class="string">'淘宝商城'</span>,</span><br><span class="line">  name: <span class="string">'淘宝'</span>,</span><br><span class="line">  num: <span class="string">'2'</span></span><br><span class="line">&#125;,&#123;</span><br><span class="line">  href: <span class="string">'http://www.qq.com'</span>,</span><br><span class="line">  title: <span class="string">'腾讯首页'</span>,</span><br><span class="line">  name: <span class="string">'腾讯'</span>,</span><br><span class="line">  num: <span class="string">'3'</span></span><br><span class="line">&#125;]);</span><br></pre></td></tr></table></figure>

<h2 id="第十七章"><a href="#第十七章" class="headerlink" title="第十七章"></a>第十七章</h2><p>观察者模式（Observer）：又叫发布-订阅者模式（Publish/Subscribe）或消息机制，它定义了一种一对多的关系，让多个观察者对象同时监听某一个主体对象，这个主体对象的状态发生变化时就会通知所有的观察者对象，使得它们能够自动更新自己。</p>
<ul>
<li>1.js - 观察者模式</li>
<li>2.js - 观察者模式在实际应用中的例子</li>
<li>3.js - 老师和学生的故事。。。</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：评论+消息通知</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 观察者模式</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 将观察者放在闭包中，当页面加载就立即执行</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Observer = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 防止消息队列暴漏而被篡改，故将消息容器作为静态私有变量保存。</span></span><br><span class="line">  <span class="keyword">var</span> __message = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">// 订阅</span></span><br><span class="line">    subscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果消息不存在则创建一个消息类型</span></span><br><span class="line">      <span class="keyword">if</span> (!__message[type]) &#123;</span><br><span class="line">        __message[type] = [fn];</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 将动作方法推送到消息对应的动作执行序列中</span></span><br><span class="line">        __message[type].push(fn);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 取消订阅</span></span><br><span class="line">    unsubscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!__message[type] || <span class="built_in">Object</span>.prototype.toString.call(__message[type]) !== <span class="string">'[object Array]'</span>) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = __message[type].length - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        __message[type][i] === fn &amp;&amp; __message[type].splice(i, <span class="number">1</span>);</span><br><span class="line">      &#125;;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 发布信息</span></span><br><span class="line">    publish: <span class="function"><span class="keyword">function</span>(<span class="params">type, args</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!__message[type]) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 定义消息信息</span></span><br><span class="line">      <span class="keyword">var</span> events = &#123;</span><br><span class="line">        type: type,</span><br><span class="line">        args: args</span><br><span class="line">      &#125;;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 执行注册的消息所对应的所有动作序列</span></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; __message[type].length; i++) &#123;</span><br><span class="line">        __message[type][i].call(<span class="keyword">this</span>, events);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 拉出来溜溜</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 订阅</span></span><br><span class="line">Observer.subscribe(<span class="string">'test'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(e);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 发布</span></span><br><span class="line">Observer.publish(<span class="string">'test'</span>, &#123;<span class="attr">msg</span>: <span class="string">'传递参数'</span>&#125;);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：评论+消息通知</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 观察者模式</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 将观察者放在闭包中，当页面加载就立即执行</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Observer = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 防止消息队列暴漏而被篡改，故将消息容器作为静态私有变量保存。</span></span><br><span class="line">  <span class="keyword">var</span> __message = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">// 注册信息接口（订阅）</span></span><br><span class="line">    subscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果消息不存在则创建一个消息类型</span></span><br><span class="line">      <span class="keyword">if</span> (!__message[type]) &#123;</span><br><span class="line">        __message[type] = [fn];</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 将动作方法推送到消息对应的动作执行序列中</span></span><br><span class="line">        __message[type].push(fn);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 发布消息接口（取消订阅）</span></span><br><span class="line">    unsubscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!__message[type] || <span class="built_in">Object</span>.prototype.toString.call(__message[type]) !== <span class="string">'[object Array]'</span>) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = __message[type].length - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        __message[type][i] === fn &amp;&amp; __message[type].splice(i, <span class="number">1</span>);</span><br><span class="line">      &#125;;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 移除信息接口（移除信息接口）</span></span><br><span class="line">    publish: <span class="function"><span class="keyword">function</span>(<span class="params">type, args</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!__message[type]) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 定义消息信息</span></span><br><span class="line">      <span class="keyword">var</span> events = &#123;</span><br><span class="line">        type: type,</span><br><span class="line">        args: args</span><br><span class="line">      &#125;;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 执行注册的消息所对应的所有动作序列</span></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; __message[type].length; i++) &#123;</span><br><span class="line">        __message[type][i].call(<span class="keyword">this</span>, events);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 外观模式</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">$</span>(<span class="params">id</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">document</span>.getElementById(id);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 工程师A</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 新增一条消息</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">addMsgItem</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> text = e.args.text;</span><br><span class="line">    <span class="keyword">var</span> ul = $(<span class="string">'msg'</span>);</span><br><span class="line">    <span class="keyword">var</span> li = <span class="built_in">document</span>.createElement(<span class="string">'li'</span>);</span><br><span class="line">    <span class="keyword">var</span> span = <span class="built_in">document</span>.createElement(<span class="string">'span'</span>);</span><br><span class="line"></span><br><span class="line">    li.innerHTML = text;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 关闭按钮</span></span><br><span class="line">    span.onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      ul.removeChild(li);</span><br><span class="line"></span><br><span class="line">      Observer.publish(<span class="string">'removeCommentMessage'</span>, &#123;</span><br><span class="line">        num: <span class="number">-1</span></span><br><span class="line">      &#125;);</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    ul.appendChild(span);</span><br><span class="line">    ul.appendChild(li);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  Observer.subscribe(<span class="string">'addCommentMessage'</span>, addMsgItem);</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 工程师B</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 修改用户消息数目</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">changeMsgNum</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> num = e.args.num;</span><br><span class="line">    $(<span class="string">'msg_num'</span>).innerHTML = <span class="built_in">parseInt</span>($(<span class="string">'msg_num'</span>).innerHTML || <span class="number">0</span>) + <span class="number">1</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 注册添加评论信息</span></span><br><span class="line">  Observer.subscribe(<span class="string">'addCommentMessage'</span>, changeMsgNum);</span><br><span class="line">  Observer.subscribe(<span class="string">'removeCommentMessage'</span>, changeMsgNum);</span><br><span class="line"></span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 工程师C</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  </span><br><span class="line">  <span class="comment">// 用户点击提交按钮</span></span><br><span class="line">  $(<span class="string">'user_submit'</span>).onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> text = $(<span class="string">'user_input'</span>);</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">if</span> (!text.value) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">    Observer.publish(<span class="string">'addCommentMessage'</span>, &#123;</span><br><span class="line">      text: text.value,</span><br><span class="line">      num: <span class="number">1</span></span><br><span class="line">    &#125;);</span><br><span class="line"></span><br><span class="line">    text.value = <span class="string">''</span>;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 测试HTML</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> *  &lt;div id="msg"&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="comment"> *  &lt;input type="text" id="user_input" /&gt;</span></span><br><span class="line"><span class="comment"> *  &lt;button id="user_submit"&gt;submite&lt;/button&gt;</span></span><br><span class="line"><span class="comment"> *  &lt;div id="msg_num"&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 观察者模式</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * 将观察者放在闭包中，当页面加载就立即执行</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> Observer = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 防止消息队列暴漏而被篡改，故将消息容器作为静态私有变量保存。</span></span><br><span class="line">  <span class="keyword">var</span> __message = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">// 注册信息接口（订阅）</span></span><br><span class="line">    subscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果消息不存在则创建一个消息类型</span></span><br><span class="line">      <span class="keyword">if</span> (!__message[type]) &#123;</span><br><span class="line">        __message[type] = [fn];</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 将动作方法推送到消息对应的动作执行序列中</span></span><br><span class="line">        __message[type].push(fn);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 发布消息接口（取消订阅）</span></span><br><span class="line">    unsubscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!__message[type] || <span class="built_in">Object</span>.prototype.toString.call(__message[type]) !== <span class="string">'[object Array]'</span>) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = __message[type].length - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        __message[type][i] === fn &amp;&amp; __message[type].splice(i, <span class="number">1</span>);</span><br><span class="line">      &#125;;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 移除信息接口（移除信息接口）</span></span><br><span class="line">    publish: <span class="function"><span class="keyword">function</span>(<span class="params">type, args</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (!__message[type]) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 定义消息信息</span></span><br><span class="line">      <span class="keyword">var</span> events = &#123;</span><br><span class="line">        type: type,</span><br><span class="line">        args: args</span><br><span class="line">      &#125;;</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 执行注册的消息所对应的所有动作序列</span></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; __message[type].length; i++) &#123;</span><br><span class="line">        __message[type][i].call(<span class="keyword">this</span>, events);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 学生类</span></span><br><span class="line"><span class="keyword">var</span> Student = <span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 学生回答结果</span></span><br><span class="line">  self.result = result;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 学生回答问题动作</span></span><br><span class="line">  self.say = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(self.result);</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 回答问题方法</span></span><br><span class="line">Student.prototype.answer = <span class="function"><span class="keyword">function</span>(<span class="params">question</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 注册参数问题</span></span><br><span class="line">  Observer.subscribe(question, <span class="keyword">this</span>.say);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">Student.prototype.sleep = <span class="function"><span class="keyword">function</span>(<span class="params">question</span>) </span>&#123;</span><br><span class="line">  Observer.unsubscribe(question, <span class="keyword">this</span>.say);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 教师类</span></span><br><span class="line"><span class="keyword">var</span> Teacher = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line">Teacher.prototype.ask = <span class="function"><span class="keyword">function</span>(<span class="params">question</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'问题是：'</span> + question);</span><br><span class="line">  <span class="comment">// 发布提问消息</span></span><br><span class="line">  Observer.publish(question);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 模拟听课的学生</span></span><br><span class="line"><span class="keyword">var</span> student1 = <span class="keyword">new</span> Student(<span class="string">'学生1回答问题'</span>);</span><br><span class="line"><span class="keyword">var</span> student2 = <span class="keyword">new</span> Student(<span class="string">'学生2回答问题'</span>);</span><br><span class="line"><span class="keyword">var</span> student3 = <span class="keyword">new</span> Student(<span class="string">'学生3回答问题'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 注册一下哪位学生回答什么问题</span></span><br><span class="line">student1.answer(<span class="string">'什么是设计模式'</span>);</span><br><span class="line">student1.answer(<span class="string">'简述观察者模式'</span>);</span><br><span class="line">student2.answer(<span class="string">'什么是设计模式'</span>);</span><br><span class="line">student3.answer(<span class="string">'什么是设计模式'</span>);</span><br><span class="line">student3.answer(<span class="string">'简述观察者模式'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 后来第三位同学睡着了。。</span></span><br><span class="line">student3.sleep(<span class="string">'简述观察者模式'</span>);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> teacher = <span class="keyword">new</span> Teacher();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 提问</span></span><br><span class="line">teacher.ask(<span class="string">'什么是设计模式'</span>);</span><br><span class="line">teacher.ask(<span class="string">'简述观察者模式'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 最后，两个问题，第一个问题三名同学回答，第二个问题只有第一名同学回答。。。</span></span><br></pre></td></tr></table></figure>



<h2 id="第十八章"><a href="#第十八章" class="headerlink" title="第十八章"></a>第十八章</h2><p>状态模式（State）：当一个对象的内部状态发生改变时，会导致其行为的改变，这看起来像是改变了对象。</p>
<ul>
<li>1.js - bad 不好的案例</li>
<li>2.js - bood 使用状态模式之后</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 这是一个反面教材</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 以超级玛丽为例子</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> lastAction = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">changeMarry</span>(<span class="params">action</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (action == <span class="string">'jump'</span>) &#123;</span><br><span class="line">    <span class="comment">// 跳跃的动作</span></span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (action == <span class="string">'move'</span>) &#123;</span><br><span class="line">    <span class="comment">// 移动动作</span></span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="comment">// 默认情况</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  lastAction = action;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 符合动作对条件判断的开销是翻倍的</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> lastAction1 = <span class="string">''</span>;</span><br><span class="line"><span class="keyword">var</span> lastAction2 = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">changeMarry2</span>(<span class="params">action1, action2</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (action1 === <span class="string">'shoot'</span>) &#123;</span><br><span class="line">    <span class="comment">// 射击动作</span></span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (action1 === <span class="string">'move'</span> &amp;&amp; action2 === <span class="string">'shoot'</span>) &#123;</span><br><span class="line">    <span class="comment">// 移动中射击</span></span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (action1 === <span class="string">'jump'</span> &amp;&amp; action2 === <span class="string">'shoot'</span>) &#123;</span><br><span class="line">    <span class="comment">// 跳跃中射击</span></span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 保留上一个动作</span></span><br><span class="line">  lastAction1 = action1 || <span class="string">''</span>;</span><br><span class="line">  lastAction2 = action2 || <span class="string">''</span>;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 超级玛丽的例子</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 创建超级玛丽状态类</span></span><br><span class="line"><span class="keyword">var</span> MarryState = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> _currentState = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 动作与状态方法映射</span></span><br><span class="line">  <span class="keyword">var</span> states = &#123;</span><br><span class="line">    jump: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 跳跃</span></span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'jump'</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    move: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 移动</span></span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'move'</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    shoot: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 射击</span></span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'shoot'</span>);</span><br><span class="line">    &#125;,</span><br><span class="line">    squat: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 蹲下</span></span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'squat'</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 动作控制类</span></span><br><span class="line">  <span class="keyword">var</span> Action = &#123;</span><br><span class="line">    changeState: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">var</span> arg = <span class="built_in">arguments</span>;</span><br><span class="line">      </span><br><span class="line">      <span class="comment">// 重置内部状态</span></span><br><span class="line">      _currentState = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (arg.length) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arg.length; i++) &#123;</span><br><span class="line">          _currentState[arg[i]] = <span class="literal">true</span>;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    goes: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="built_in">console</span>.log(<span class="string">'触发一次动作'</span>);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> _currentState) &#123;</span><br><span class="line">        states[i] &amp;&amp; states[i]();</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    change: Action.changeState,</span><br><span class="line">    goes: Action.goes</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 两种执行方式，可以直接执行状态类，也可以实例化状态类</span></span><br><span class="line"><span class="comment">// 直接执行状态类：如果直接使用实例化类就只能自己使用，如果还有另一个人使用，就可能会修改状态类内部的状态</span></span><br><span class="line"><span class="comment">// 实例化状态类：实例化状态类有一个好处就是 它是对状态类的复制，无论怎么使用，都不会影响我，</span></span><br><span class="line"><span class="keyword">var</span> marry = <span class="keyword">new</span> MarryState();</span><br><span class="line"></span><br><span class="line">marry.change(<span class="string">'jump'</span>, <span class="string">'shoot'</span>).goes().goes().change(<span class="string">'shoot'</span>).goes();</span><br></pre></td></tr></table></figure>

<h2 id="第十九章"><a href="#第十九章" class="headerlink" title="第十九章"></a>第十九章</h2><p>策略模式（Strategy）：将定义的一组算法封装起来，使其相互之间可以替换。封装的算法具有一定独立性，不会随客户端变化而变化。</p>
<ul>
<li>1.js - 策略模式</li>
<li>2.js - 策略模式（表单验证）</li>
</ul>
<p>策略模式最主要的特色是创建一系列策略算法，魅族算法处理的业务都是相同的，只是处理的过程或者处理的结果不一样，所以它们又是可以相互替换的，这样就解决了算法与使用者之间的耦合。在测试层面上讲，由于每组算法相互之间的独立性，该模式更方便与对每组算法进行单元测试，保证算法的质量。</p>
<p>对于策略模式的有点可以归纳为3点</p>
<ol>
<li>策略模式封装了一组代码族，并且封装的代码相互之间独立，便于对算法的重复引用，提高了算法的复用率</li>
<li>策略模式与继承相比，在类的继承中继承的方法是被封装在类中，因此当需求很多算法时，就不得不创建出多种类，这样会导致算法与算法的使用者耦合在一起，不利于算法的独立演化，并且在类的外部改变类的算法难度也是极大的。</li>
<li>同状态模式一样，策略模式也是一种优化分支判断语句的模式，采用策略模式对算法封装使得算法更利于维护。</li>
</ol>
<p>当然，策略模式也有缺点。由于选择哪种算法的决定权在用户，所以对用户来说就必须了解每种算法的实现。这就增加了用户的使用成本。其次，由于每种算法间相互独立，这样对于一些复杂的算法处理相同逻辑的部分无法实现共享，这就会造成一些资源的浪费。当然你可以通过享元模式（第十三章）来解决。</p>
<p>对于分支语句的优化，目前为止已经学了3种，分别为工厂方法模式，状态模式与策略模式。对于工厂方法模式来说，它是一种创建型模式，它的最终目的是创建对象。而状态模式与策略模式都是行为性模式，不过在状态模式中，其核心是对状态的控制来决定表现行为，所以状态之间通常是不能相互替代的，否则将产生不同的行为结果。而策略模式核心是算法，由于每种算法都要处理的业务逻辑相同，因此他们可以相互替换，当然策略模式并不关心使用者的环境，因为同一种策略模式最宠产出的结果是一定的。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：过节商品打折，一部分商品5折出售，一部分8折出售，一部分商品9折出售，等到元旦，我们要搞一个幸运反馈活动，普通用户满100返30，高级VIP用户满100返50... </span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 价格策略对象</span></span><br><span class="line"><span class="keyword">var</span> PriceStrategy = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 内部算法对象</span></span><br><span class="line">  <span class="keyword">var</span> stragtegy = &#123;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 100返30</span></span><br><span class="line">    return30: <span class="function"><span class="keyword">function</span>(<span class="params">price</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> +price + <span class="built_in">parseInt</span>(price / <span class="number">100</span>) * <span class="number">30</span>;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 满100返50</span></span><br><span class="line">    return50: <span class="function"><span class="keyword">function</span>(<span class="params">price</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> +price + <span class="built_in">parseInt</span>(price / <span class="number">100</span>) * <span class="number">50</span>;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 九折</span></span><br><span class="line">    percent90: <span class="function"><span class="keyword">function</span>(<span class="params">price</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="number">90</span> / <span class="number">100</span> * +price;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 八折</span></span><br><span class="line">    percent80: <span class="function"><span class="keyword">function</span>(<span class="params">price</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="number">80</span> / <span class="number">100</span> * +price;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 五折</span></span><br><span class="line">    percent50: <span class="function"><span class="keyword">function</span>(<span class="params">price</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="number">50</span> / <span class="number">100</span> * +price;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 策略算法调用接口</span></span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">algorithm, price</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 如果算法存在，则调用算法，否则返回false</span></span><br><span class="line">    <span class="keyword">return</span> stragtegy[algorithm] &amp;&amp; stragtegy[algorithm](price);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> price = PriceStrategy(<span class="string">'return50'</span>, <span class="string">'314.67'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(price); <span class="comment">// 464.67</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> InputStrategy = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> strategy = &#123;</span><br><span class="line">    isNumber: <span class="function"><span class="keyword">function</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">Object</span>.prototype.toString.call(value) === <span class="string">'[object Array]'</span>;</span><br><span class="line">    &#125;,</span><br><span class="line">    phone: <span class="function"><span class="keyword">function</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="regexp">/^1[3578]\d&#123;9&#125;$/</span>.test(value);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    check: <span class="function"><span class="keyword">function</span>(<span class="params">type, value</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 去除首尾空白符</span></span><br><span class="line">      value = value.replace(<span class="regexp">/^\s+|\s+$/g</span>, <span class="string">''</span>);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> strategy[type] ? strategy[type](value) : <span class="string">'没有该类型的检测方法'</span>;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 添加策略</span></span><br><span class="line">    addStrategy: <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      strategy[type] = fn;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line">InputStrategy.addStrategy(<span class="string">'mail'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">value</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="regexp">/^(\w+)(@\w+)(\.\w+)+$/</span>.test(value);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> is = InputStrategy.check(<span class="string">'mail'</span>, <span class="string">'abc@gmail.com'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(is);</span><br></pre></td></tr></table></figure>

<h2 id="第二十章"><a href="#第二十章" class="headerlink" title="第二十章"></a>第二十章</h2><p>责任链模式（Chain of Responsibility）：解决请求的发送者与请求的接受者之间的耦合，通过职责链上的多个对象对分解请求流程，实现请求在多个对象之间的传递，直到最后一个对象完成请求的处理。</p>
<ul>
<li>1.js - 责任链模式</li>
</ul>
<p>责任链模式定义了请求的传递方向，通过多个函数对请求的传递，实现一个复杂的逻辑操作。因此责任链模式将负责的需求颗粒化逐一实现每个函数分内的需求，并将请求顺序地传递。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：项目经理准备改善页面中的输入验证与输入提示交互体验，如用户在输入框输入信息后，在输入框的下面提示出一些备选项，当用户输入完成后，则要对用户输入的信息进行验证等。</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 异步请求对象（伪代码）</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * data 请求数据</span></span><br><span class="line"><span class="comment"> * dealType 相应数据处理对象</span></span><br><span class="line"><span class="comment"> * dom 事件源</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> sendData = <span class="function"><span class="keyword">function</span>(<span class="params">data, dealType, dom</span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// ... 这是一个ajax请求代码</span></span><br><span class="line"></span><br><span class="line">  <span class="comment">// 请求成功之后回调函数</span></span><br><span class="line">  <span class="keyword">var</span> result = [<span class="string">'嘿嘿嘿'</span>, <span class="string">'哈哈哈'</span>, <span class="string">'呵呵呵'</span>];</span><br><span class="line">  dealData(result, dealType, dom);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 处理响应数据</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * data 相应数据</span></span><br><span class="line"><span class="comment"> * dealType 相应数据处理对象</span></span><br><span class="line"><span class="comment"> * dom 事件源</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> dealData = <span class="function"><span class="keyword">function</span>(<span class="params">data, dealType, dom</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> dataType = <span class="built_in">Object</span>.prototype.toString.call(data);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">switch</span>(dealType) &#123;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'sug'</span>:</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (dataType === <span class="string">'[object Array]'</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> createSug(data, dom);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (dataType === <span class="string">'[object Object]'</span>) &#123;</span><br><span class="line">        <span class="keyword">var</span> newData = [];</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> data) &#123;</span><br><span class="line">          newData.push(data[i]);</span><br><span class="line">        &#125;</span><br><span class="line"></span><br><span class="line">        <span class="keyword">return</span> createSug(newData, dom);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> createSug([data], dom);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">    <span class="keyword">case</span> <span class="string">'validate'</span>:</span><br><span class="line">      <span class="keyword">return</span> createValidataResult(data, dom);</span><br><span class="line">      <span class="keyword">break</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 创建提示框组件</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * data 响应适配数据</span></span><br><span class="line"><span class="comment"> * dom 事件源</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> createSug = <span class="function"><span class="keyword">function</span>(<span class="params">data, dom</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> html = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.length; i++) &#123;</span><br><span class="line">    html += <span class="string">'&lt;li&gt;'</span> + data[i] + <span class="string">'&lt;/li&gt;'</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  dom.parentNode.getElementsByTagName(<span class="string">'ul'</span>)[<span class="number">0</span>].innerHTML = html;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 创建校验组件</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * data 响应适配数据</span></span><br><span class="line"><span class="comment"> * dom 事件源</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> createValidataResult = <span class="function"><span class="keyword">function</span>(<span class="params">data, dom</span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 显示校验结果</span></span><br><span class="line">  dom.parentNode.getElementsByTagName(<span class="string">'span'</span>)[<span class="number">0</span>].innerHTML = data;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<h2 id="第二十一章"><a href="#第二十一章" class="headerlink" title="第二十一章"></a>第二十一章</h2><p>命令模式（Command）：将请求与实现解耦，并封装成独立对象，从而使不同的请求对客户端的实现参数化。</p>
<ul>
<li>1.js - 命令模式</li>
</ul>
<p>命令模式是将执行的命令封装，解决命令的发起者与命令的执行者之间的耦合。每一条命令实质上是一个操作。命令的使用者不必要了解命令的执行者（命令对象）的命令接口是如何实现的，命令式如何接收的，命令式如何执行的。所有的命令都被存储在命令对象中。</p>
<p>命令模式的有点自然是解决命令使用者之间的耦合。新的命令很容易加入到命令系统中，供使用者使用。命令的使用具有一致性，多数的命令在一定程度上是简化操作方法的使用的。</p>
<p>命令模式是对一些操作的封装，这就造成每执行一次操作都要调用一次命令对象，增加了系统的复杂度。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 实现模块</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> ViewCommand = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 模板</span></span><br><span class="line">  <span class="keyword">var</span> tpl = &#123;</span><br><span class="line">    product: [</span><br><span class="line">      <span class="string">'&lt;div&gt;'</span>,</span><br><span class="line">        <span class="string">'&lt;img src="&#123;#src#&#125;" /&gt;'</span>,</span><br><span class="line">        <span class="string">'&lt;p&gt;&#123;#text#&#125;&lt;/p&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;/div&gt;'</span></span><br><span class="line">    ].join(<span class="string">''</span>),</span><br><span class="line"></span><br><span class="line">    title: [</span><br><span class="line">      <span class="string">'&lt;div class="title"&gt;'</span>,</span><br><span class="line">        <span class="string">'&lt;div class="main"&gt;'</span>,</span><br><span class="line">          <span class="string">'&lt;h2&gt;&#123;#title#&#125;&lt;/h2&gt;'</span>,</span><br><span class="line">          <span class="string">'&lt;p&gt;&#123;#tips#&#125;&lt;/p&gt;'</span>,</span><br><span class="line">        <span class="string">'&lt;/div&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;/div&gt;'</span></span><br><span class="line">    ].join(<span class="string">''</span>),</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> html = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 替换数据</span></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">formatString</span>(<span class="params">str, obj</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> str.replace(<span class="regexp">/\&#123;#(\w+)#\&#125;/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">match, key</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> obj[key];</span><br><span class="line">    &#125;);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 方法集合</span></span><br><span class="line">  <span class="keyword">var</span> Action = &#123;</span><br><span class="line">    create: <span class="function"><span class="keyword">function</span>(<span class="params">data, view</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果是数字则把数组中的每一项加进html中</span></span><br><span class="line">      <span class="keyword">if</span> (<span class="built_in">Object</span>.prototype.toString.call(data) === <span class="string">'[object Array]'</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.length; i++) &#123;</span><br><span class="line">          html += formatString(tpl[view], data[i]);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        html += formatString(tpl[view], data);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line">    display: <span class="function"><span class="keyword">function</span>(<span class="params">container, data, view</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 如果有数据，根据数据创建视图</span></span><br><span class="line">      <span class="keyword">if</span> (data) <span class="keyword">this</span>.create(data, view);</span><br><span class="line"></span><br><span class="line">      <span class="built_in">document</span>.getElementById(container).innerHTML  = html;</span><br><span class="line">      html = <span class="string">''</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> <span class="title">excute</span>(<span class="params">command</span>) </span>&#123;</span><br><span class="line">    command.param = <span class="built_in">Object</span>.prototype.toString.call(command.param) === <span class="string">'[object Array]'</span> ? command.param : [command.param];</span><br><span class="line">    Action[command.cd].apply(Action, command.param);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 测试</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 产品展示数据</span></span><br><span class="line"><span class="keyword">var</span> productData = [&#123;</span><br><span class="line">  src: <span class="string">'command/02.jpg'</span>,</span><br><span class="line">  text: <span class="string">'绽放的桃花'</span></span><br><span class="line">&#125;,&#123;</span><br><span class="line">  src: <span class="string">'command/03.jpg'</span>,</span><br><span class="line">  text: <span class="string">'阳光下的温馨'</span></span><br><span class="line">&#125;,&#123;</span><br><span class="line">  src: <span class="string">'command/04.jpg'</span>,</span><br><span class="line">  text: <span class="string">'镜头前的绿色'</span></span><br><span class="line">&#125;];</span><br><span class="line"></span><br><span class="line"><span class="comment">// 模块标题数据</span></span><br><span class="line"><span class="keyword">var</span> titleData = &#123;</span><br><span class="line">  title: <span class="string">'夏日里的一片温馨'</span>,</span><br><span class="line">  tips: <span class="string">'暖暖的温情带给人们家的感受'</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">ViewCommand(&#123;</span><br><span class="line">  cd: <span class="string">'display'</span>,</span><br><span class="line">  param: [<span class="string">'title'</span>, titleData, <span class="string">'title'</span>]</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">ViewCommand(&#123;</span><br><span class="line">  cd: <span class="string">'create'</span>,</span><br><span class="line">  param: [&#123;</span><br><span class="line">    src: <span class="string">'command/01.jpg'</span>,</span><br><span class="line">    text: <span class="string">'迎着朝阳的野菊花'</span></span><br><span class="line">  &#125;, <span class="string">'product'</span>]</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">ViewCommand(&#123;</span><br><span class="line">  cd: <span class="string">'display'</span>,</span><br><span class="line">  param: [<span class="string">'product'</span>, productData, <span class="string">'product'</span>]</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 测试HTML</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * &lt;div id="title"&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="comment"> * &lt;div id="product"&gt;&lt;/div&gt;</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<h2 id="第二十二章"><a href="#第二十二章" class="headerlink" title="第二十二章"></a>第二十二章</h2><p>访问者模式（Visitor）：针对于对象结构中的元素，定义在不改变该对象的前提下访问结构中元素的新方法。</p>
<ul>
<li>1.js - 访问者模式</li>
<li>2.js - 访问者模式2</li>
</ul>
<p>访问者模式解决数据与数据的操作方法之间的耦合，将数据的操作方法独立于数据，使其可以自由化演变。（我觉得本章主要讲的就是Object.prototype.toString.call这样的使用方式）</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bindIEEvent</span>(<span class="params">dom, type, fn, data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> data = data || &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  dom.attachEvent(<span class="string">'on'</span> + type, <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">    fn.call(dom, e, data);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 我觉得这一章主要讲的是 call 的应用。。</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 访问器</span></span><br><span class="line"><span class="keyword">var</span> Visitor = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    splice: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 获取参数，从第二个方法算起</span></span><br><span class="line">      <span class="keyword">var</span> args = <span class="built_in">Array</span>.prototype.splice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 对第一个参数执行splice方法</span></span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">Array</span>.prototype.splice.apply(<span class="built_in">arguments</span>[<span class="number">0</span>], args);</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    push: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 获取参数，从第二个方法算起</span></span><br><span class="line">      <span class="keyword">var</span> args = <span class="built_in">Array</span>.prototype.splice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">Array</span>.prototype.push.apply(<span class="built_in">arguments</span>[<span class="number">0</span>], args);</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    pop: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="built_in">Array</span>.prototype.pop.apply(<span class="built_in">arguments</span>[<span class="number">0</span>]);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = &#123;&#125;;</span><br><span class="line"><span class="built_in">console</span>.log(a.length);</span><br><span class="line"></span><br><span class="line">Visitor.push(a, <span class="number">1</span>, <span class="number">2</span>, <span class="number">3</span>, <span class="number">4</span>, <span class="number">5</span>);</span><br><span class="line"><span class="built_in">console</span>.log(a.length);</span><br><span class="line"></span><br><span class="line">Visitor.push(a, <span class="number">6</span>, <span class="number">7</span>, <span class="number">8</span>, <span class="number">9</span>);</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'push:'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br><span class="line"><span class="built_in">console</span>.log(a.length);</span><br><span class="line"></span><br><span class="line">Visitor.pop(a);</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'pop:'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br><span class="line"><span class="built_in">console</span>.log(a.length);</span><br><span class="line"></span><br><span class="line">Visitor.splice(a, <span class="number">2</span>, <span class="number">2</span>);</span><br><span class="line"><span class="built_in">console</span>.log(<span class="string">'splice:'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(a);</span><br><span class="line"><span class="built_in">console</span>.log(a.length);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 我觉得本章主要讲的内容就是 call 和 apply 的应用</span></span><br></pre></td></tr></table></figure>

<h2 id="第二十三章"><a href="#第二十三章" class="headerlink" title="第二十三章"></a>第二十三章</h2><p>中介者模式（Mediator）</p>
<p>通过终结者对象封装一系列对象之间的交互，使对象之间不再相互引用，降低它们之间的耦合。有时中介者对象也可改变对象之间的交互。</p>
<ul>
<li>1.js - 中介者模式</li>
<li>2.js - 中介者模式(实际中的例子)</li>
</ul>
<p>个人理解：虽然跟观察者模式有点像，但还是不一样的，观察者模式是双向的，订阅者也可以是发布者，而中介者模式的发布者有中介对象统一发布。。</p>
<p>中介者是单向的，类似于执行某个事件，然后所有订阅过该事件的都会执行。</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 中介者对象</span></span><br><span class="line"><span class="keyword">var</span> Mediator = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 消息对象</span></span><br><span class="line">  <span class="keyword">var</span> _msg = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    subscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, action</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (_msg[type]) &#123;</span><br><span class="line">        _msg[type].push(action);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        _msg[type] = [];</span><br><span class="line">        _msg[type].push(action);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    send: <span class="function"><span class="keyword">function</span>(<span class="params">type</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (_msg[type]) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; _msg[type].length; i++) &#123;</span><br><span class="line">          _msg[type][i] &amp;&amp; _msg[type][i]();</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 单元测试</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 订阅</span></span><br><span class="line">Mediator.subscribe(<span class="string">'demo'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'first'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">Mediator.subscribe(<span class="string">'demo'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'second'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">Mediator.send(<span class="string">'demo'</span>);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 中介者对象</span></span><br><span class="line"><span class="keyword">var</span> Mediator = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 消息对象</span></span><br><span class="line">  <span class="keyword">var</span> _msg = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    subscribe: <span class="function"><span class="keyword">function</span>(<span class="params">type, action</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (_msg[type]) &#123;</span><br><span class="line">        _msg[type].push(action);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        _msg[type] = [];</span><br><span class="line">        _msg[type].push(action);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    send: <span class="function"><span class="keyword">function</span>(<span class="params">type</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (_msg[type]) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; _msg[type].length; i++) &#123;</span><br><span class="line">          _msg[type][i] &amp;&amp; _msg[type][i]();</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 显示隐藏导航小组件</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * mod 模块</span></span><br><span class="line"><span class="comment"> * tag 标签</span></span><br><span class="line"><span class="comment"> * showOrHide 显示还是隐藏</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="keyword">var</span> showHideNavWidget = <span class="function"><span class="keyword">function</span>(<span class="params">mod, tag, showOrHide</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> mod = <span class="built_in">document</span>.getElementById(mod);</span><br><span class="line">  <span class="keyword">var</span> tag = mod.getElementsByTagName(tag);</span><br><span class="line">  <span class="keyword">var</span> showOrHide = (!showOrHide || showOrHide === <span class="string">'hide'</span>) ? <span class="string">'hidden'</span> : <span class="string">'visible'</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 占位隐藏这些标签</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; tag.length; i ++) &#123;</span><br><span class="line">    tag[i].style.visibility = showOrHide;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 用户手册导航模块</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 订阅 隐藏用户收藏导航信息提醒消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'hideAllNavNum'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'collection_nav'</span>, <span class="string">'b'</span>, <span class="literal">false</span>);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 订阅 显示用户收藏导航信息提醒消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'showAllNavNum'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'collection_nav'</span>, <span class="string">'b'</span>, <span class="literal">true</span>);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 订阅 隐藏用户收藏导航网址消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'hideAllNavUrl'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'collection_nav'</span>, <span class="string">'span'</span>, <span class="literal">false</span>);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 订阅 显示用户收藏导航网址消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'showAllNavUrl'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'collection_nav'</span>, <span class="string">'span'</span>, <span class="literal">true</span>);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 推荐用户导航</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 订阅 隐藏推荐用户导航消息提醒消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'hideAllNavNum'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'recommend_nav'</span>, <span class="string">'b'</span>, <span class="literal">false</span>);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 订阅 显示推荐用户导航消息提醒消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'showAllNavNum'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'recommend_nav'</span>, <span class="string">'b'</span>, <span class="literal">true</span>);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 最近常用导航</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 订阅 隐藏最近常用导航网址消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'hideAllNavUrl'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'recently_nav'</span>, <span class="string">'span'</span>, <span class="string">'hide'</span>);</span><br><span class="line">  &#125;);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 订阅 显示最近常用导航网址消息</span></span><br><span class="line">  Mediator.subscribe(<span class="string">'showAllNavUrl'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    showHideNavWidget(<span class="string">'recently_nav'</span>, <span class="string">'span'</span>, <span class="string">'show'</span>);</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 设置层模块</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line">(<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 消息提醒选框</span></span><br><span class="line">  <span class="keyword">var</span> hideNum = <span class="built_in">document</span>.getElementById(<span class="string">'hide_num'</span>);</span><br><span class="line">  <span class="keyword">var</span> hideUrl = <span class="built_in">document</span>.getElementById(<span class="string">'hide_url'</span>);</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 消息提醒选框事件</span></span><br><span class="line">  hideNum.onchange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (hideNum.checked) &#123;</span><br><span class="line">      Mediator.send(<span class="string">'hideAllNavNum'</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      Mediator.send(<span class="string">'showAllNavNum'</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 网址选框事件</span></span><br><span class="line">  hideUrl.onchange = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">if</span> (hideUrl.checked) &#123;</span><br><span class="line">      Mediator.send(<span class="string">'hideAllNavUrl'</span>);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      Mediator.send(<span class="string">'showAllNavUrl'</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 测试html</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">网址 &lt;input type="checkbox" id="hide_num"&gt;</span></span><br><span class="line"><span class="comment">url &lt;input type="checkbox" id="hide_url"&gt;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&lt;div id="collection_nav"&gt;</span></span><br><span class="line"><span class="comment">    用户手册导航模块</span></span><br><span class="line"><span class="comment">    &lt;b&gt;b&lt;/b&gt;</span></span><br><span class="line"><span class="comment">    &lt;span&gt;span&lt;/span&gt;</span></span><br><span class="line"><span class="comment">&lt;/div&gt;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&lt;div id="recommend_nav"&gt;</span></span><br><span class="line"><span class="comment">    推荐用户导航</span></span><br><span class="line"><span class="comment">    &lt;b&gt;b&lt;/b&gt;</span></span><br><span class="line"><span class="comment">&lt;/div&gt;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">&lt;div id="recently_nav"&gt;</span></span><br><span class="line"><span class="comment">    最近常用导航</span></span><br><span class="line"><span class="comment">    &lt;span&gt;span&lt;/span&gt;</span></span><br><span class="line"><span class="comment">&lt;/div&gt;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<h2 id="第二十四章"><a href="#第二十四章" class="headerlink" title="第二十四章"></a>第二十四章</h2><p>备忘录模式（Memento）</p>
<p>我的理解，其实就是一个普通的缓存机制。。</p>
<ul>
<li>1.js - 备忘录模式</li>
<li>2.js - 我自己写的缓存工具函数</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：上一页下一页</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Page</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> cache = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">page, fn</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 如果有缓存</span></span><br><span class="line">    <span class="keyword">if</span> (cache[page]) &#123;</span><br><span class="line">      fn &amp;&amp; fn(cache[page]);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      $.<span class="keyword">get</span>('./data/getxxx').success(function(data) &#123;</span><br><span class="line">        cache[page] = data;</span><br><span class="line">        fn &amp;&amp; fn(data);</span><br><span class="line">      &#125;);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Cache = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> _cache = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 设置缓存</span></span><br><span class="line"><span class="comment">     *</span></span><br><span class="line"><span class="comment">     * key 键</span></span><br><span class="line"><span class="comment">     * data 缓存数据</span></span><br><span class="line"><span class="comment">     * cover 是否覆盖（默认不覆盖）</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">set</span>: function(key, data, cover) &#123;</span><br><span class="line">      <span class="keyword">if</span> (!_cache[key] || cover) &#123;</span><br><span class="line">        _cache[key] = data;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 获取缓存</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">get</span>: function(key) &#123;</span><br><span class="line">      <span class="keyword">return</span> _cache[key];</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 清除缓存</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    del: <span class="function"><span class="keyword">function</span>(<span class="params">key</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">delete</span> _cache[key];</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">Cache.set(<span class="string">'test'</span>, &#123;<span class="attr">name</span>: <span class="string">'berwin'</span>&#125;);</span><br><span class="line"><span class="built_in">console</span>.log(Cache.get(<span class="string">'test'</span>));</span><br><span class="line"></span><br><span class="line">Cache.del(<span class="string">'test'</span>);</span><br><span class="line"><span class="built_in">console</span>.log(Cache.get(<span class="string">'test'</span>));</span><br></pre></td></tr></table></figure>

<h2 id="第二十五章"><a href="#第二十五章" class="headerlink" title="第二十五章"></a>第二十五章</h2><p>迭代器模式（Iterator）</p>
<p>在不暴露对象内部结构的同时，可以顺序地访问聚合对象内部的元素</p>
<ul>
<li>1.js - 迭代器模式（一个幻灯片的基类案例）</li>
<li>2.js - forEach的实现</li>
<li>3.js - 对象迭代器的实现</li>
<li>4.js - 取值器</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：页面中有好多焦点图，每一种都要重写一遍元素循环，所以需要建立一个基类，然后让不同种类的焦点图（轮播，淡入淡出）继承基类，此外，迭代器模式比较适合解决重复循环迭代的问题</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 迭代器</span></span><br><span class="line"><span class="keyword">var</span> Iterator = <span class="function"><span class="keyword">function</span>(<span class="params">items, container</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> container = container &amp;&amp; <span class="built_in">document</span>.getElementById(container) || <span class="built_in">document</span>;</span><br><span class="line">  <span class="keyword">var</span> items = container.getElementsByTagName(items);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> length = items.length;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 当前索引</span></span><br><span class="line">  <span class="keyword">var</span> index = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> splice = <span class="built_in">Array</span>.prototype.splice;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 获取第一个元素</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    first: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      index = <span class="number">0</span>;</span><br><span class="line">      <span class="keyword">return</span> items[index];</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 获取最后一个元素</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    second: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      index = length - <span class="number">1</span>;</span><br><span class="line">      <span class="keyword">return</span> items[index];</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 获取前一个元素</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    prev: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (--index &gt; <span class="number">0</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> items[index];</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        index = <span class="number">0</span>;</span><br><span class="line">        <span class="keyword">return</span> items[index];</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 获取后一个元素</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    next: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (++index &lt; length) &#123;</span><br><span class="line">        <span class="keyword">return</span> items[index];</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        index = length - <span class="number">1</span>;</span><br><span class="line">        <span class="keyword">return</span> items[index];</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 获取某一个元素</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    <span class="keyword">get</span>: function(num) &#123;</span><br><span class="line">      index = num &gt;= <span class="number">0</span> ? num % length : num % length + length;</span><br><span class="line">      <span class="keyword">return</span> items[index];</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 对每一个元素执行某一个方法</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    dealEach: <span class="function"><span class="keyword">function</span>(<span class="params">fn</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">var</span> args = splice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; length; i++) &#123;</span><br><span class="line">        fn.apply(items[i], args);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 对某一个元素执行某一个方法</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    dealItem: <span class="function"><span class="keyword">function</span>(<span class="params">num, fn</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">var</span> args = splice.call(<span class="built_in">arguments</span>, <span class="number">2</span>);</span><br><span class="line">      <span class="comment">// 通过this.get方法设置index索引值</span></span><br><span class="line">      fn.apply(<span class="keyword">this</span>.get(num), args);</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    <span class="comment">/*</span></span><br><span class="line"><span class="comment">     * 排他方式处理某一个元素</span></span><br><span class="line"><span class="comment">     */</span></span><br><span class="line">    exclusive: <span class="function"><span class="keyword">function</span>(<span class="params">num, allFn, numFn</span>) </span>&#123;</span><br><span class="line">      <span class="comment">// 对所有元素执行回调函数</span></span><br><span class="line">      <span class="keyword">this</span>.dealEach(allFn);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 如果num为数组</span></span><br><span class="line">      <span class="keyword">if</span> (<span class="built_in">Object</span>.prototype.toString.call(num) === <span class="string">'[object Array]'</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; num.length; i++) &#123;</span><br><span class="line">          <span class="keyword">this</span>.dealItem(num[i], numFn);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">this</span>.dealItem(num, numFn);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> test =  Iterator(<span class="string">'li'</span>, <span class="string">'container'</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(test.first());</span><br><span class="line"><span class="built_in">console</span>.log(test.prev());</span><br><span class="line"><span class="built_in">console</span>.log(test.next());</span><br><span class="line"><span class="built_in">console</span>.log(test.get(<span class="number">2000</span>));</span><br><span class="line"></span><br><span class="line"><span class="comment">// 处理所有元素</span></span><br><span class="line">test.dealEach(<span class="function"><span class="keyword">function</span>(<span class="params">text, color</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.innerHTML = text;</span><br><span class="line">  <span class="keyword">this</span>.style.background = color;</span><br><span class="line">&#125;, <span class="string">'test'</span>, <span class="string">'pink'</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 排他思想处理第3个与第4个元素</span></span><br><span class="line">test.exclusive([<span class="number">2</span>, <span class="number">3</span>], <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.innerHTML = <span class="string">'被排除的'</span>;</span><br><span class="line">  <span class="keyword">this</span>.style.background = <span class="string">'green'</span>;</span><br><span class="line">&#125;, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.innerHTML = <span class="string">'选中的'</span>;</span><br><span class="line">  <span class="keyword">this</span>.style.background = <span class="string">'red'</span>;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试HTML</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*&lt;ul id="container"&gt;</span></span><br><span class="line"><span class="comment">  &lt;li&gt;&lt;/li&gt;</span></span><br><span class="line"><span class="comment">  &lt;li&gt;&lt;/li&gt;</span></span><br><span class="line"><span class="comment">  &lt;li&gt;&lt;/li&gt;</span></span><br><span class="line"><span class="comment">  &lt;li&gt;&lt;/li&gt;</span></span><br><span class="line"><span class="comment">&lt;/ul&gt;*/</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> forEach = <span class="function"><span class="keyword">function</span>(<span class="params">arr, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">    fn(arr[i], i, arr);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">forEach([<span class="number">1</span>,<span class="number">2</span>,<span class="number">3</span>,<span class="number">4</span>], <span class="function"><span class="keyword">function</span>(<span class="params">item, i, arr</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(item, i, arr);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> eachObject = <span class="function"><span class="keyword">function</span>(<span class="params">obj, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> obj) &#123;</span><br><span class="line">    fn(obj[i], i, obj);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">eachObject(&#123;<span class="attr">a</span>: <span class="string">'123'</span>, <span class="attr">b</span>: <span class="string">'456'</span>, <span class="attr">c</span>: <span class="string">'789'</span>&#125;, <span class="function"><span class="keyword">function</span>(<span class="params">item, key, obj</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(item, key, obj);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = &#123;</span><br><span class="line">  common: &#123;&#125;,</span><br><span class="line">  client: &#123;</span><br><span class="line">    user: &#123;</span><br><span class="line">      username: <span class="string">'berwin'</span>,</span><br><span class="line">      uid: <span class="string">'123'</span></span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line">  server: &#123;&#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 如果不知道服务器是否会将该属性或者该属性的上级属性正确的打印到页面中，直接获取属性会导致报错，所以每次操作都要一层一层做安全检查 var test = a &amp;&amp; a.client &amp;&amp; a.client.user &amp;&amp; a.client.user.username;</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过迭代器我们即可减少编写这类校验代码</span></span><br><span class="line"><span class="keyword">var</span> getter = <span class="function"><span class="keyword">function</span>(<span class="params">data, key</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (!data) <span class="keyword">return</span> <span class="literal">undefined</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> result = data;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> keys = key.split(<span class="string">'.'</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; keys.length; i++) &#123;</span><br><span class="line">    <span class="keyword">if</span> (result[keys[i]]) &#123;</span><br><span class="line">      result = result[keys[i]];</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="literal">undefined</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> result;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log( getter(a, <span class="string">'client.user.username'</span>) ); <span class="comment">// berwin</span></span><br></pre></td></tr></table></figure>

<h2 id="第二十六章"><a href="#第二十六章" class="headerlink" title="第二十六章"></a>第二十六章</h2><p>解释器模式（Interpreter）</p>
<ul>
<li>1.js - 解释器模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 个人觉得这章讲的并不是设计模式。</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 获取兄弟元素名称</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">getSublingName</span>(<span class="params">node</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (node.previousSibling) &#123;</span><br><span class="line">    <span class="keyword">var</span> name = <span class="string">''</span>;</span><br><span class="line">    <span class="keyword">var</span> count = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">var</span> nodeName = node.nodeName;</span><br><span class="line">    <span class="keyword">var</span> sibling = node.previousSibling;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">while</span> (sibling) &#123;</span><br><span class="line">      <span class="comment">// 如果节点为元素 并且 节点类型与前一个兄弟类型相同，并且前一个兄弟元素名称存在</span></span><br><span class="line">      <span class="keyword">if</span> (sibling.nodeType == <span class="number">1</span> &amp;&amp; sibling.nodeType === node.nodeType &amp;&amp; sibling.nodeName) &#123;</span><br><span class="line">        <span class="keyword">if</span> (nodeName == sibling.nodeName) &#123;</span><br><span class="line">          name += ++count;</span><br><span class="line">        &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">          <span class="comment">// 重置相同紧邻节点名称节点个数</span></span><br><span class="line">          count = <span class="number">1</span>;</span><br><span class="line">          name += <span class="string">'|'</span> + sibling.nodeName.toUpperCase();</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      sibling = sibling.previousSibling;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> name;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">''</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// XPath 解释器</span></span><br><span class="line"><span class="keyword">var</span> Interpreter = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">node, wrap</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> path = [];</span><br><span class="line">    wrap = wrap || <span class="built_in">document</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 如果当前（目标）节点等于容器节点</span></span><br><span class="line">    <span class="keyword">if</span> (node === wrap) &#123;</span><br><span class="line">      <span class="keyword">if</span> (wrap.nodeType === <span class="number">1</span>) &#123;</span><br><span class="line">        path.push( wrap.nodeName.toUpperCase() );</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> path;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (node.parentNode !== wrap) &#123;</span><br><span class="line">      path = Interpreter(node.parentNode, wrap);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">if</span> (wrap.nodeType == <span class="number">1</span>) &#123;</span><br><span class="line">        path.push( wrap.nodeName.toUpperCase() );</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> sublingsNames = getSublingName(node);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (node.nodeType == <span class="number">1</span>) &#123;</span><br><span class="line">      path.push(node.nodeName.toUpperCase() + sublingsNames);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> path;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> path = Interpreter(<span class="built_in">document</span>.getElementById(<span class="string">'test'</span>));</span><br><span class="line"><span class="built_in">console</span>.log(path.join(<span class="string">'&gt;'</span>)); <span class="comment">// HTML&gt;BODY|HEAD&gt;P2</span></span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试html</span></span><br><span class="line"><span class="comment">// &lt;p id="test"&gt;222&lt;/p&gt;</span></span><br></pre></td></tr></table></figure>

<h2 id="第二十七章"><a href="#第二十七章" class="headerlink" title="第二十七章"></a>第二十七章</h2><p>链模式（Operate of Responsibility）</p>
<p>通过在对象方法中将当前对象返回，实现对同一个对象多个方法的链式调用。</p>
<ul>
<li>1.js - 链模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> A = <span class="function"><span class="keyword">function</span>(<span class="params">selector</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">new</span> A.fn.init(selector);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.fn = A.prototype = &#123;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">constructor</span>: A,</span><br><span class="line"></span><br><span class="line">  // 一些浏览器引擎在判断对象是否是数组的时候，不仅仅判断有没有length属性，是否通过‘[索引值]’方式访问元素，还会判断是否具有数组方法来确定是否要用数组的形式展现</span><br><span class="line">  // 所以添加几个数组常用的方法增强数组特性</span><br><span class="line">  push: Array.prototype.push,</span><br><span class="line">  sort: Array.prototype.sort,</span><br><span class="line">  splice: Array.prototype.splice,</span><br><span class="line"></span><br><span class="line">  init: function(selector) &#123;</span><br><span class="line">    <span class="keyword">this</span>[<span class="number">0</span>] = <span class="built_in">document</span>.getElementById(selector);</span><br><span class="line">    <span class="keyword">this</span>.length = <span class="number">1</span>;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  size: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.length;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line">A.fn.init.prototype = A.fn;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 对象扩展</span></span><br><span class="line">A.extend = A.fn.extend = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 扩展对象从第二个参数算起</span></span><br><span class="line">  <span class="keyword">var</span> i = <span class="number">1</span>;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获取参数长度</span></span><br><span class="line">  <span class="keyword">var</span> len = <span class="built_in">arguments</span>.length;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 第一个参数为源对象</span></span><br><span class="line">  <span class="keyword">var</span> target = <span class="built_in">arguments</span>[<span class="number">0</span>];</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (i == len) &#123;</span><br><span class="line">    <span class="comment">// 源对象等于当前对象</span></span><br><span class="line">    target = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// i从0计数</span></span><br><span class="line">    i--;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (; i &lt; len; i++) &#123;</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> j <span class="keyword">in</span> <span class="built_in">arguments</span>[i]) &#123;</span><br><span class="line">        target[j] = <span class="built_in">arguments</span>[i][j];</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> target;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.fn.extend(&#123;</span><br><span class="line">  <span class="comment">// 添加事件</span></span><br><span class="line">  on: (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">type, fn</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">if</span> (<span class="built_in">document</span>.addEventListener) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="keyword">this</span>.length; i++) &#123;</span><br><span class="line">          <span class="keyword">this</span>[i].addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125; <span class="keyword">else</span> <span class="keyword">if</span> (<span class="built_in">document</span>.attachEvent) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="keyword">this</span>.length; i++) &#123;</span><br><span class="line">          <span class="keyword">this</span>[i].attachEvent(<span class="string">'on'</span> + type, fn);</span><br><span class="line">        &#125;</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; <span class="keyword">this</span>.length; i++) &#123;</span><br><span class="line">          <span class="keyword">this</span>[i][<span class="string">'on'</span> + type] = fn;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;)(),</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 设置属性</span></span><br><span class="line">  attr: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> arg = <span class="built_in">arguments</span>;</span><br><span class="line">    <span class="keyword">var</span> len = arg.length;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">this</span>.length &lt; <span class="number">1</span>) <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (len === <span class="number">1</span>) &#123;</span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">typeof</span> arg[<span class="number">0</span>] === <span class="string">'string'</span>) &#123;</span><br><span class="line">        <span class="keyword">return</span> <span class="keyword">this</span>[<span class="number">0</span>].getAttribute(arg[<span class="number">0</span>]);</span><br><span class="line">      &#125;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">typeof</span> arg[<span class="number">0</span>] === <span class="string">'object'</span>) &#123;</span><br><span class="line">        <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> arg[<span class="number">0</span>]) &#123;</span><br><span class="line">          <span class="keyword">for</span> (<span class="keyword">var</span> j = <span class="number">0</span>; j &lt; <span class="keyword">this</span>.length; j++) &#123;</span><br><span class="line">            <span class="keyword">return</span> <span class="keyword">this</span>[j].setAttribute(i, arg[<span class="number">0</span>][i]);</span><br><span class="line">          &#125;</span><br><span class="line">        &#125;</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> <span class="keyword">if</span> (len === <span class="number">2</span>) &#123;</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> j = <span class="number">0</span>; j &lt; <span class="keyword">this</span>.length; j++) &#123;</span><br><span class="line">        <span class="keyword">this</span>[j].setAttribute(arg[<span class="number">0</span>], arg[<span class="number">1</span>]);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">A(<span class="string">'test'</span>).attr(<span class="string">'class'</span>, <span class="string">'demo'</span>).on(<span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'clicked'</span>);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试html</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">&lt;div id="test"&gt;test&lt;/div&gt;</span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<h2 id="第二十八章"><a href="#第二十八章" class="headerlink" title="第二十八章"></a>第二十八章</h2><p>委托模式</p>
<p>其实就是事件委托</p>
<ul>
<li>1.js - 事件委托</li>
<li>2.js - 事件委托2（通过事件委托为 当前页面不存在的元素 绑定事件）</li>
<li>3.js - 事件委托3（解决内存泄露）</li>
<li>4.js - 事件委托4（数据分发）</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// bad</span></span><br><span class="line"><span class="keyword">var</span> ul = <span class="built_in">document</span>.getElementById(<span class="string">'container'</span>);</span><br><span class="line"><span class="keyword">var</span> li = ul.getElementsByTagName(<span class="string">'li'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; li.length; i++) &#123;</span><br><span class="line">  li[i].onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">this</span>.style.backgroundColor = <span class="string">'grey'</span>;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// good</span></span><br><span class="line">ul.onclick = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> event = e || event;</span><br><span class="line">  <span class="keyword">var</span> target = e.target || e.srcElement;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (target.nodeName.toLowerCase() === <span class="string">'li'</span>) &#123;</span><br><span class="line">    target.style.backgroundColor = <span class="string">'grey'</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 通过事件委托为 当前页面不存在的元素 绑定事件</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> article = <span class="built_in">document</span>.getElementById(<span class="string">'article'</span>);</span><br><span class="line">article.onclick = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> event = e || event;</span><br><span class="line">  <span class="keyword">var</span> target = event.target || event.srcElement;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (target.nodeName.toLowerCase() === <span class="string">'p'</span>) &#123;</span><br><span class="line">    target.innerHTML = <span class="string">'我要改变这段内容'</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> p = <span class="built_in">document</span>.createElement(<span class="string">'p'</span>);</span><br><span class="line">p.innerHTML = <span class="string">'新增一段内容'</span>;</span><br><span class="line">article.appendChild(p);</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试html</span></span><br><span class="line"><span class="comment">// &lt;div id="article"&gt;呵呵哒&lt;/div&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试html</span></span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment">&lt;div id="container"&gt;</span></span><br><span class="line"><span class="comment">  &lt;button id="btn"&gt;demo&lt;/button&gt;</span></span><br><span class="line"><span class="comment">&lt;/div&gt; </span></span><br><span class="line"><span class="comment">*/</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> g = <span class="function"><span class="keyword">function</span>(<span class="params">id</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">document</span>.getElementById(id);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">g(<span class="string">'btn'</span>).onclick = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  g(<span class="string">'container'</span>).innerHTML = <span class="string">'触发了事件'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// IE低版本问题</span></span><br><span class="line"><span class="comment">// 触发事件时，会把按钮自身替换掉，事件并没有清除，所以会泄露到内存中</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// good</span></span><br><span class="line">g(<span class="string">'container'</span>).onclick = <span class="function"><span class="keyword">function</span>(<span class="params">e</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> target = e &amp;&amp; e.target || event.srcElement;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (target.id === <span class="string">'btn'</span>) &#123;</span><br><span class="line">    g(<span class="string">'container'</span>).innerHTML = <span class="string">'触发了事件'</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// bad</span></span><br><span class="line">$.<span class="keyword">get</span>('/banner', function(result) &#123;</span><br><span class="line">  <span class="comment">// banner...</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$.<span class="keyword">get</span>('/aside', function(result) &#123;</span><br><span class="line">  <span class="comment">// aside...</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$.<span class="keyword">get</span>('/article', function(result) &#123;</span><br><span class="line">  <span class="comment">// article...</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$.<span class="keyword">get</span>('/member', function(result) &#123;</span><br><span class="line">  <span class="comment">// member...</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">$.<span class="keyword">get</span>('/message', function(result) &#123;</span><br><span class="line">  <span class="comment">// message...</span></span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">// good</span></span><br><span class="line"><span class="keyword">var</span> Deal = &#123;</span><br><span class="line">  banner: <span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// banner...</span></span><br><span class="line">  &#125;,</span><br><span class="line">  aside: <span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// aside...</span></span><br><span class="line">  &#125;,</span><br><span class="line">  article: <span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// article...</span></span><br><span class="line">  &#125;,</span><br><span class="line">  member: <span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// member...</span></span><br><span class="line">  &#125;,</span><br><span class="line">  message: <span class="function"><span class="keyword">function</span>(<span class="params">result</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// message...</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">$.<span class="keyword">get</span>('/deal', function(result) &#123;</span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> result) &#123;</span><br><span class="line">    Deal[i] &amp;&amp; Deal[i](result[i]);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="第二十九章"><a href="#第二十九章" class="headerlink" title="第二十九章"></a>第二十九章</h2><p>数据访问对象模式</p>
<ul>
<li>1.js - localStorage封装</li>
</ul>
<p>这不是设计模式，只是一个对localstorage的一个封装</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br><span class="line">119</span><br><span class="line">120</span><br><span class="line">121</span><br><span class="line">122</span><br><span class="line">123</span><br><span class="line">124</span><br><span class="line">125</span><br><span class="line">126</span><br><span class="line">127</span><br><span class="line">128</span><br><span class="line">129</span><br><span class="line">130</span><br><span class="line">131</span><br><span class="line">132</span><br><span class="line">133</span><br><span class="line">134</span><br><span class="line">135</span><br><span class="line">136</span><br><span class="line">137</span><br><span class="line">138</span><br><span class="line">139</span><br><span class="line">140</span><br><span class="line">141</span><br><span class="line">142</span><br><span class="line">143</span><br><span class="line">144</span><br><span class="line">145</span><br><span class="line">146</span><br><span class="line">147</span><br><span class="line">148</span><br><span class="line">149</span><br><span class="line">150</span><br><span class="line">151</span><br><span class="line">152</span><br><span class="line">153</span><br><span class="line">154</span><br><span class="line">155</span><br><span class="line">156</span><br><span class="line">157</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> BaseLocalStorage = <span class="function"><span class="keyword">function</span>(<span class="params">preId, timeSign</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.preId = preId;</span><br><span class="line">  <span class="keyword">this</span>.timeSign = timeSign || <span class="string">'|-|'</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">BaseLocalStorage.prototype = &#123;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 操作状态</span></span><br><span class="line">  status: &#123;</span><br><span class="line">    SUCCESS: <span class="number">0</span>,</span><br><span class="line">    FAILURE: <span class="number">1</span>,</span><br><span class="line">    OVERFLOW: <span class="number">2</span>,</span><br><span class="line">    TIMEOUT: <span class="number">3</span></span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 保存本地存储链接</span></span><br><span class="line">  storage: localStorage || <span class="built_in">window</span>.localStorage,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 获取真实字段</span></span><br><span class="line">  getKey: <span class="function"><span class="keyword">function</span>(<span class="params">key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">this</span>.preId + key;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 添加（修改）数据</span></span><br><span class="line"><span class="comment">   *</span></span><br><span class="line"><span class="comment">   * @param key 键</span></span><br><span class="line"><span class="comment">   * @param value 值</span></span><br><span class="line"><span class="comment">   * @param callback(status, key, value) 回调函数</span></span><br><span class="line"><span class="comment">   * @param time 过期时间</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  <span class="keyword">set</span>: function(key, value, callback, time) &#123;</span><br><span class="line">    <span class="keyword">var</span> status = <span class="keyword">this</span>.status.SUCCESS;</span><br><span class="line">    <span class="keyword">var</span> key = <span class="keyword">this</span>.getKey(key);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      time = <span class="keyword">new</span> <span class="built_in">Date</span>(time).getTime() || time.getTime();</span><br><span class="line">    &#125; <span class="keyword">catch</span>(e) &#123;</span><br><span class="line">      time = <span class="keyword">new</span> <span class="built_in">Date</span>().getTime() + <span class="number">1000</span> * <span class="number">60</span> * <span class="number">60</span> * <span class="number">24</span> * <span class="number">31</span>;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      <span class="comment">// 添加数据</span></span><br><span class="line">      <span class="keyword">this</span>.storage.setItem(key, time + <span class="keyword">this</span>.timeSign + value);</span><br><span class="line">    &#125; <span class="keyword">catch</span>(e) &#123;</span><br><span class="line">      <span class="comment">// 溢出失败，返回溢出状态</span></span><br><span class="line">      status = <span class="keyword">this</span>.status.OVERFLOW;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 有回调函数则执行回调函数并传入参数操作状态，真实数据字段标识以及存储数据值</span></span><br><span class="line">    callback &amp;&amp; callback.call(<span class="keyword">this</span>, status, key, value);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 获取数据</span></span><br><span class="line"><span class="comment">   *</span></span><br><span class="line"><span class="comment">   * @param key 键</span></span><br><span class="line"><span class="comment">   * @param callback(status, value) 回调函数</span></span><br><span class="line"><span class="comment">   * @return &#123;status: status, value: value&#125;</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  <span class="keyword">get</span>: function(key, callback) &#123;</span><br><span class="line">    <span class="keyword">var</span> status = <span class="keyword">this</span>.status.SUCCESS;</span><br><span class="line">    <span class="keyword">var</span> key = <span class="keyword">this</span>.getKey(key);</span><br><span class="line">    <span class="keyword">var</span> value = <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">var</span> timeSignLen = <span class="keyword">this</span>.timeSign.length;</span><br><span class="line">    <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line">    <span class="keyword">var</span> result = <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      value = self.storage.getItem(key);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (e) &#123;</span><br><span class="line">      <span class="comment">// 不支持localstorage的浏览器</span></span><br><span class="line">      result = &#123;</span><br><span class="line">        status: self.status.FAILURE,</span><br><span class="line">        value: <span class="literal">null</span></span><br><span class="line">      &#125;;</span><br><span class="line"></span><br><span class="line">      callback &amp;&amp; callback.call(self, result.status, result.value);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">return</span> result;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (value) &#123;</span><br><span class="line">      <span class="comment">// 获取时间戳与存储数据之间的拼接符起始位置</span></span><br><span class="line">      <span class="keyword">var</span> index = value.indexOf(self.timeSign);</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 获取时间戳</span></span><br><span class="line">      <span class="keyword">var</span> time = +value.slice(<span class="number">0</span>, index);</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (<span class="keyword">new</span> <span class="built_in">Date</span>(time).getTime() &gt; <span class="keyword">new</span> <span class="built_in">Date</span>().getTime() || time == <span class="number">0</span>) &#123;</span><br><span class="line">        value = value.slice(index + timeSignLen);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        <span class="comment">// 如果时间为过期</span></span><br><span class="line">        value = <span class="literal">null</span>;</span><br><span class="line">        status = self.status.FAILURE;</span><br><span class="line">        self.remove(key);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      status = self.status.FAILURE;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    result = &#123;</span><br><span class="line">      status: status,</span><br><span class="line">      value: value</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    callback &amp;&amp; callback.call(self, result.status, result.value);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> result;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 删除数据</span></span><br><span class="line">  remove: <span class="function"><span class="keyword">function</span> (<span class="params">key, callback</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> status = <span class="keyword">this</span>.status.FAILURE;</span><br><span class="line">    <span class="keyword">var</span> key = <span class="keyword">this</span>.getKey(key);</span><br><span class="line">    <span class="keyword">var</span> value = <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">try</span> &#123;</span><br><span class="line">      value = <span class="keyword">this</span>.storage.getItem(key);</span><br><span class="line">    &#125; <span class="keyword">catch</span> (e) &#123;&#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (value) &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        <span class="keyword">this</span>.storage.removeItem(key);</span><br><span class="line"></span><br><span class="line">        status = <span class="keyword">this</span>.status.SUCCESS;</span><br><span class="line">      &#125; <span class="keyword">catch</span>(e) &#123;&#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    callback &amp;&amp; callback.call(<span class="keyword">this</span>, status, status &gt; <span class="number">0</span> ? <span class="literal">null</span> : value.slice(value.indexOf(<span class="keyword">this</span>.timeSign) + <span class="keyword">this</span>.timeSign.length));</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> db = <span class="keyword">new</span> BaseLocalStorage(<span class="string">'bw_'</span>);</span><br><span class="line">db.set(<span class="string">'test'</span>, <span class="string">'hahaha'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">status, value</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'set:'</span>, status, value);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">db.get(<span class="string">'test'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">status, value</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'get:'</span>, status, value);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">db.remove(<span class="string">'test'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">status, value</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'remove:'</span>, status, value);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">db.remove(<span class="string">'test'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">status, value</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'remove'</span>, status, value);</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">db.get(<span class="string">'test'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">status, value</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'get:'</span>, status, value);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="第三十章"><a href="#第三十章" class="headerlink" title="第三十章"></a>第三十章</h2><p>节流模式</p>
<p>本章不属于设计模式的范畴，所以不写例子了，本章主要讲了几个方面</p>
<ul>
<li>返回顶部抖动问题</li>
<li>鼠标移出延迟隐藏浮动层</li>
<li>图片延迟加载</li>
<li>统计打包</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"></span><br></pre></td></tr></table></figure>

<h2 id="第三十一章"><a href="#第三十一章" class="headerlink" title="第三十一章"></a>第三十一章</h2><p>简单模板模式</p>
<ul>
<li>1.js - 模板模式</li>
<li>2.js - 模板模式2</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> A = A || &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 主体展示区容器</span></span><br><span class="line">A.root = <span class="built_in">document</span>.getElementById(<span class="string">'container'</span>);</span><br><span class="line"></span><br><span class="line">A.formateString = <span class="function"><span class="keyword">function</span>(<span class="params">tpl, data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> tpl.replace(<span class="regexp">/\&#123;#(\w+)#\&#125;/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">match, key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">typeof</span> data[key] === <span class="literal">undefined</span> ? <span class="string">''</span> : data[key];</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.strategy = &#123;</span><br><span class="line">  listPart: <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> s = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>);</span><br><span class="line">    <span class="keyword">var</span> list = data.list;</span><br><span class="line">    <span class="keyword">var</span> ul = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> tpl = [</span><br><span class="line">      <span class="string">'&lt;h2&gt;&#123;#h2#&#125;&lt;/h2&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;p&gt;&#123;#p#&#125;&lt;/p&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;ul&gt;&#123;#ul#&#125;&lt;/ul&gt;'</span></span><br><span class="line">    ].join(<span class="string">''</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> liTpl = [</span><br><span class="line">      <span class="string">'&lt;li&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;strong&gt;&#123;#strong#&#125;&lt;/strong&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;span&gt;&#123;#span#&#125;&lt;/span&gt;'</span>,</span><br><span class="line">      <span class="string">'&lt;/li&gt;'</span></span><br><span class="line">    ].join(<span class="string">''</span>);</span><br><span class="line"></span><br><span class="line">    data.id &amp;&amp; (s.id = data.id);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; list.length; i++) &#123;</span><br><span class="line">      <span class="keyword">if</span> (list[i].strong || list[i].span) &#123;</span><br><span class="line">        ul += A.formateString(liTpl, list[i]);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    data.ul = ul;</span><br><span class="line"></span><br><span class="line">    s.innerHTML = A.formateString(tpl, data);</span><br><span class="line"></span><br><span class="line">    A.root.appendChild(s);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">A.strategy.listPart(&#123;<span class="attr">h2</span>: <span class="string">'berwin'</span>, <span class="attr">p</span>: <span class="string">'adfsf'</span>, <span class="attr">list</span>: [&#123;<span class="attr">strong</span>: <span class="string">'strong'</span>, <span class="attr">span</span>: <span class="string">'span'</span>&#125;, &#123;<span class="attr">strong</span>: <span class="string">'strong1'</span>, <span class="attr">span</span>: <span class="string">'span1'</span>&#125;]&#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试html</span></span><br><span class="line"><span class="comment">// &lt;div id="container"&gt;&lt;/div&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> A = A || &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 主体展示区容器</span></span><br><span class="line">A.root = <span class="built_in">document</span>.getElementById(<span class="string">'container'</span>);</span><br><span class="line"></span><br><span class="line">A.formateString = <span class="function"><span class="keyword">function</span>(<span class="params">tpl, data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> tpl.replace(<span class="regexp">/\&#123;#(\w+)#\&#125;/g</span>, <span class="function"><span class="keyword">function</span>(<span class="params">match, key</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">typeof</span> data[key] === <span class="literal">undefined</span> ? <span class="string">''</span> : data[key];</span><br><span class="line">  &#125;);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.view = <span class="function"><span class="keyword">function</span>(<span class="params">name</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="built_in">Object</span>.prototype.toString.call(name) === <span class="string">'[object Array]'</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> tpl = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; name.length; i++) &#123;</span><br><span class="line">      tpl += A.view(name[i]);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> tpl;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="string">'&lt;'</span>+ name +<span class="string">'&gt;&#123;#'</span>+ name +<span class="string">'#&#125;&lt;/'</span>+ name +<span class="string">'&gt;'</span>;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">A.strategy = &#123;</span><br><span class="line">  listPart: <span class="function"><span class="keyword">function</span>(<span class="params">data</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> s = <span class="built_in">document</span>.createElement(<span class="string">'div'</span>);</span><br><span class="line">    <span class="keyword">var</span> list = data.list;</span><br><span class="line">    <span class="keyword">var</span> ul = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">var</span> tpl = A.view([<span class="string">'h2'</span>, <span class="string">'p'</span>, <span class="string">'ul'</span>]);</span><br><span class="line">    </span><br><span class="line">    <span class="keyword">var</span> li = A.view(<span class="string">'li'</span>);</span><br><span class="line">    <span class="keyword">var</span> liSon = A.view([<span class="string">'strong'</span>, <span class="string">'span'</span>]);</span><br><span class="line">    <span class="keyword">var</span> liTpl = A.formateString(li, &#123;<span class="attr">li</span>: liSon&#125;);</span><br><span class="line"></span><br><span class="line">    data.id &amp;&amp; (s.id = data.id);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; list.length; i++) &#123;</span><br><span class="line">      <span class="keyword">if</span> (list[i].strong || list[i].span) &#123;</span><br><span class="line">        ul += A.formateString(liTpl, list[i]);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    data.ul = ul;</span><br><span class="line"></span><br><span class="line">    s.innerHTML = A.formateString(tpl, data);</span><br><span class="line"></span><br><span class="line">    A.root.appendChild(s);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">A.strategy.listPart(&#123;<span class="attr">h2</span>: <span class="string">'berwin'</span>, <span class="attr">p</span>: <span class="string">'adfsf'</span>, <span class="attr">list</span>: [&#123;<span class="attr">strong</span>: <span class="string">'strong'</span>, <span class="attr">span</span>: <span class="string">'span'</span>&#125;, &#123;<span class="attr">strong</span>: <span class="string">'strong1'</span>, <span class="attr">span</span>: <span class="string">'span1'</span>&#125;]&#125;)</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试html</span></span><br><span class="line"><span class="comment">// &lt;div id="container"&gt;&lt;/div&gt;</span></span><br></pre></td></tr></table></figure>

<h2 id="第三十二章"><a href="#第三十二章" class="headerlink" title="第三十二章"></a>第三十二章</h2><p>惰性模式（layier）</p>
<p>减少每次代码执行时的重复性的分支判断，通过对对象重新定义来屏蔽原对象中的分支判断</p>
<ul>
<li>1.js - 惰性模式（加载时执行）</li>
<li>2.js - 惰性模式（调用时执行）</li>
</ul>
<p>个人觉得这章的内容还是挺有用的</p>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 背景：每次执行方法都要进行一次判定，但其实是可以优化的</span></span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> A = &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// bad</span></span><br><span class="line">A.on = <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (dom.addEventListener) &#123;</span><br><span class="line">    dom.addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (dom.attachEvent) &#123;</span><br><span class="line">    dom.attachEvent(type, fn);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    dom[<span class="string">'on'</span> + type] = fn;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(A.on)</span><br><span class="line"></span><br><span class="line"><span class="comment">// bood</span></span><br><span class="line">A.on = (<span class="function"><span class="keyword">function</span>(<span class="params">dom</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (dom.addEventListener) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">      dom.addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (dom.attachEvent) &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">      dom.attachEvent(type, fn);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">      dom[<span class="string">'on'</span> + type] = fn;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)(<span class="built_in">document</span>);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(A.on);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> A = &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// bad</span></span><br><span class="line">A.on = <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (dom.addEventListener) &#123;</span><br><span class="line">    dom.addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (dom.attachEvent) &#123;</span><br><span class="line">    dom.attachEvent(type, fn);</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    dom[<span class="string">'on'</span> + type] = fn;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// bood</span></span><br><span class="line"></span><br><span class="line">A.on = <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (dom.addEventListener) &#123;</span><br><span class="line">    A.on = <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">      dom.addEventListener(type, fn, <span class="literal">false</span>);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125; <span class="keyword">else</span> <span class="keyword">if</span> (dom.attachEvent) &#123;</span><br><span class="line">    A.on = <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">      dom.attachEvent(type, fn);</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    A.on = <span class="function"><span class="keyword">function</span>(<span class="params">dom, type, fn</span>) </span>&#123;</span><br><span class="line">      dom[<span class="string">'on'</span> + type] = fn;</span><br><span class="line">    &#125;;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  A.on(dom, type, fn);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(A.on)</span><br><span class="line"></span><br><span class="line">A.on(<span class="built_in">document</span>, <span class="string">'click'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;&#125;);</span><br><span class="line"></span><br><span class="line"><span class="built_in">console</span>.log(A.on)</span><br></pre></td></tr></table></figure>

<h2 id="第三十三章"><a href="#第三十三章" class="headerlink" title="第三十三章"></a>第三十三章</h2><p>参与者模式（participator）</p>
<p>在特定的作用域中执行给定的函数，并将参数原封不动地传递</p>
<ul>
<li>1.js - bind</li>
<li>2.js - bind应用于事件</li>
<li>3.js - 原声bind写法</li>
<li>4.js - 函数柯里化</li>
<li>5.js - 重构bind</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bind</span>(<span class="params">fn, context</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> fn.apply(context, <span class="built_in">arguments</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  name: <span class="string">'berwin'</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params">age</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="keyword">this</span>.name, age);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = bind(test, obj);</span><br><span class="line">a(<span class="number">20</span>); <span class="comment">// berwin 20</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bind</span>(<span class="params">fn, context</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> fn.apply(context, <span class="built_in">arguments</span>);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> btn = <span class="built_in">document</span>.getElementById(<span class="string">'btn'</span>);</span><br><span class="line"><span class="keyword">var</span> p = <span class="built_in">document</span>.getElementById(<span class="string">'p'</span>);</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">demoFn</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="built_in">arguments</span>, <span class="keyword">this</span>);</span><br><span class="line">  btn.removeEventListener(<span class="string">'click'</span>, bindFn);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> bindFn = bind(demoFn, p);</span><br><span class="line"></span><br><span class="line">btn.addEventListener(<span class="string">'click'</span>, bindFn, <span class="literal">false</span>);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">// 另一种简单的写法</span></span><br><span class="line"><span class="comment">function test() &#123;</span></span><br><span class="line"><span class="comment">  (function() &#123;</span></span><br><span class="line"><span class="comment">    console.log(this)</span></span><br><span class="line"><span class="comment">    btn.removeEventListener('click', test);</span></span><br><span class="line"><span class="comment">  &#125;).call(p);</span></span><br><span class="line"><span class="comment">&#125;</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">btn.addEventListener('click', test, false);</span></span><br><span class="line"><span class="comment"></span></span><br><span class="line"><span class="comment">*/</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  name: <span class="string">'berwin'</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">test</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="keyword">this</span>)</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> a = test.bind(obj);</span><br><span class="line"></span><br><span class="line">a(); <span class="comment">// &#123; name: 'berwin' &#125;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">curry</span>(<span class="params">fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> slice = <span class="built_in">Array</span>.prototype.slice;</span><br><span class="line">  <span class="keyword">var</span> args = slice.call(<span class="built_in">arguments</span>, <span class="number">1</span>);</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> addArgs = slice.call(<span class="built_in">arguments</span>);</span><br><span class="line">    <span class="keyword">var</span> allArgs = args.concat(addArgs);</span><br><span class="line">    <span class="keyword">return</span> fn.apply(<span class="literal">null</span>, allArgs);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">add</span>(<span class="params">num1, num2</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> num1 + num2;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> test = curry(add, <span class="number">5</span>);</span><br><span class="line"><span class="built_in">console</span>.log( test(<span class="number">5</span>) ); <span class="comment">// 10</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">bind</span>(<span class="params">fn, context</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> slice = <span class="built_in">Array</span>.prototype.slice;</span><br><span class="line">  <span class="keyword">var</span> args = slice.call(<span class="built_in">arguments</span>, <span class="number">2</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> addArgs = slice.call(<span class="built_in">arguments</span>);</span><br><span class="line">    <span class="keyword">var</span> allArgs = args.concat(addArgs);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> fn.apply(context, allArgs);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> btn = <span class="built_in">document</span>.getElementById(<span class="string">'btn'</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> obj = &#123;</span><br><span class="line">  name: <span class="string">'berwin'</span></span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">demo</span>(<span class="params">obj, e</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="built_in">arguments</span>);</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> test = bind(demo, btn, obj);</span><br><span class="line"></span><br><span class="line">btn.addEventListener(<span class="string">'click'</span>, test);</span><br></pre></td></tr></table></figure>

<h2 id="第三十四章"><a href="#第三十四章" class="headerlink" title="第三十四章"></a>第三十四章</h2><p>等待者模式（waiter）</p>
<p>通过对多个异步进程监听，来触发未来发生的动作</p>
<ul>
<li>1.js - 等待者模式(模拟一个简单的promise)</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br><span class="line">112</span><br><span class="line">113</span><br><span class="line">114</span><br><span class="line">115</span><br><span class="line">116</span><br><span class="line">117</span><br><span class="line">118</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> Waiter = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> dfd = [];</span><br><span class="line">  <span class="keyword">var</span> doneArr = [];</span><br><span class="line">  <span class="keyword">var</span> failArr = [];</span><br><span class="line">  <span class="keyword">var</span> slice = <span class="built_in">Array</span>.prototype.slice;</span><br><span class="line">  <span class="keyword">var</span> self = <span class="keyword">this</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> Primise = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 监控对象是否解决成功状态</span></span><br><span class="line">    <span class="keyword">this</span>.resolved = <span class="literal">false</span>;</span><br><span class="line">    <span class="comment">// 监控对象是否解决失败状态</span></span><br><span class="line">    <span class="keyword">this</span>.rejected = <span class="literal">false</span>;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  Primise.prototype = &#123;</span><br><span class="line">    resolve: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">this</span>.resolved = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (!dfd.length) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = dfd.length - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">        <span class="comment">// 如果有任意一个监控对象没有被解决或者解决失败则返回</span></span><br><span class="line">        <span class="keyword">if</span> (dfd[i] &amp;&amp; !dfd[i].resolved || dfd[i].rejected) <span class="keyword">return</span>;</span><br><span class="line">        <span class="comment">// 清除监控对象</span></span><br><span class="line">        dfd.splice(i, <span class="number">1</span>);</span><br><span class="line">      &#125;;</span><br><span class="line"></span><br><span class="line">      _exec(doneArr);</span><br><span class="line">    &#125;,</span><br><span class="line"></span><br><span class="line">    reject: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">this</span>.rejected = <span class="literal">true</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (!dfd.length) <span class="keyword">return</span>;</span><br><span class="line"></span><br><span class="line">      dfd.splice(<span class="number">0</span>);</span><br><span class="line"></span><br><span class="line">      _exec(failArr);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  self.Deferred = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> Primise();</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="function"><span class="keyword">function</span> <span class="title">_exec</span>(<span class="params">arr</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; arr.length; i++) &#123;</span><br><span class="line">      <span class="keyword">try</span> &#123;</span><br><span class="line">        arr[i] &amp;&amp; arr[i]();</span><br><span class="line">      &#125; <span class="keyword">catch</span>(e) &#123;&#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 监控异步方法</span></span><br><span class="line"><span class="comment">   * </span></span><br><span class="line"><span class="comment">   * @param 监控对象</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  self.when = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    dfd = slice.call(<span class="built_in">arguments</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = dfd.length - <span class="number">1</span>; i &gt;= <span class="number">0</span>; i--) &#123;</span><br><span class="line">      <span class="keyword">if</span> (!dfd[i] || dfd[i].resolved || dfd[i].rejected || !dfd[i] <span class="keyword">instanceof</span> Primise) &#123;</span><br><span class="line">        dfd.splice(i, <span class="number">1</span>);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> self;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 添加成功回调函数的方法</span></span><br><span class="line">  self.done = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    doneArr = doneArr.concat(slice.call(<span class="built_in">arguments</span>));</span><br><span class="line">    <span class="keyword">return</span> self;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 添加失败回调函数的方法</span></span><br><span class="line">  self.fail = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    failArr = failArr.concat(slice.call(<span class="built_in">arguments</span>));</span><br><span class="line">    <span class="keyword">return</span> self;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line"><span class="comment">// 测试</span></span><br><span class="line"><span class="keyword">var</span> waiter = <span class="keyword">new</span> Waiter();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> first = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> dtd = waiter.Deferred();</span><br><span class="line"></span><br><span class="line">  setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'first finish'</span>);</span><br><span class="line">    dtd.resolve();</span><br><span class="line">  &#125;, <span class="number">5000</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> dtd;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> second = (<span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> dtd = waiter.Deferred();</span><br><span class="line"></span><br><span class="line">  setTimeout(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="built_in">console</span>.log(<span class="string">'second finish'</span>);</span><br><span class="line">    dtd.resolve();</span><br><span class="line">  &#125;, <span class="number">3000</span>);</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> dtd;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line">waiter.when(first, second).done(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'success'</span>);</span><br><span class="line">&#125;, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'success again'</span>);</span><br><span class="line">&#125;).fail(<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log(<span class="string">'fail'</span>);</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="第三十五章"><a href="#第三十五章" class="headerlink" title="第三十五章"></a>第三十五章</h2><p>同步模块模式（waiter）</p>
<ul>
<li>1.js - 同步模块模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> F = F || &#123;&#125;;</span><br><span class="line"></span><br><span class="line">F.define = <span class="function"><span class="keyword">function</span>(<span class="params">str, fn</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> parts = str.split(<span class="string">'.'</span>);</span><br><span class="line">  <span class="keyword">var</span> old = <span class="keyword">this</span>;</span><br><span class="line">  <span class="keyword">var</span> parent = <span class="keyword">this</span>;</span><br><span class="line">  <span class="keyword">var</span> i = <span class="number">0</span>;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (parts[<span class="number">0</span>] === <span class="string">'F'</span>) &#123;</span><br><span class="line">    parts = parts.slice(<span class="number">1</span>);</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 如果是框架内部方法，return</span></span><br><span class="line">  <span class="keyword">if</span> (parts[<span class="number">0</span>] === <span class="string">'define'</span> || parts[<span class="number">0</span>] === <span class="string">'module'</span>) &#123;</span><br><span class="line">    <span class="keyword">return</span>;</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> len = parts.length; i &lt; len; i++) &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> parent[parts[i]] === <span class="string">'undefined'</span>) &#123;</span><br><span class="line">      parent[parts[i]] = &#123;&#125;;</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    old = parent;</span><br><span class="line"></span><br><span class="line">    parent = parent[parts[i]];</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">if</span> (fn) &#123;</span><br><span class="line">    <span class="comment">// 此时i等于parts.length故减一</span></span><br><span class="line">    old[parts[--i]] = fn();</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">F.module = <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> args = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>);</span><br><span class="line">  <span class="keyword">var</span> fn = args.pop();</span><br><span class="line">  <span class="keyword">var</span> parts = args[<span class="number">0</span>] &amp;&amp; args[<span class="number">0</span>] <span class="keyword">instanceof</span> <span class="built_in">Array</span> ? args[<span class="number">0</span>] : args;</span><br><span class="line">  <span class="keyword">var</span> modules = [];</span><br><span class="line">  <span class="keyword">var</span> modIDs = <span class="string">''</span>;</span><br><span class="line">  <span class="keyword">var</span> i = <span class="number">0</span>;</span><br><span class="line">  <span class="keyword">var</span> ilen = parts.length;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">while</span> (i &lt; ilen) &#123;</span><br><span class="line">    <span class="keyword">if</span> (<span class="keyword">typeof</span> parts[i] === <span class="string">'string'</span>) &#123;</span><br><span class="line">      <span class="keyword">var</span> parent = <span class="keyword">this</span>;</span><br><span class="line">      modIDs = parts[i].replace(<span class="regexp">/^F\./</span>, <span class="string">''</span>).split(<span class="string">'.'</span>);</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> j = <span class="number">0</span>; j &lt; modIDs.length; j++) &#123;</span><br><span class="line">        parent = parent[modIDs[j]] || <span class="literal">false</span>;</span><br><span class="line">      &#125;</span><br><span class="line">      modules.push(parent);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      modules.push(parent[i]);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    i++</span><br><span class="line">  &#125;</span><br><span class="line"></span><br><span class="line">  fn.apply(<span class="literal">null</span>, modules);</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line">F.define(<span class="string">'string'</span>, <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    trim: <span class="function"><span class="keyword">function</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> str.replace(<span class="regexp">/^\s+|\s+$/g</span>, <span class="string">''</span>);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">F.module(<span class="string">'string.trim'</span>, <span class="function"><span class="keyword">function</span>(<span class="params">trim</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log( trim(<span class="string">' 测试一下 '</span>) );</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line">F.module([<span class="string">'string'</span>], <span class="function"><span class="keyword">function</span>(<span class="params">string</span>) </span>&#123;</span><br><span class="line">  <span class="built_in">console</span>.log( string.trim(<span class="string">' 测试一下2 '</span>) );</span><br><span class="line">&#125;);</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 总结</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * define方法就是以第一个参数为key，第二个参数为value在F对象上添加一个方法，当然中间会有一个判断神马的</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * module方法就是以第一个参数为key读取F对象上的方法push到数组中，用参数统一传给第二个参数</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> */</span></span><br></pre></td></tr></table></figure>

<h2 id="第三十六章"><a href="#第三十六章" class="headerlink" title="第三十六章"></a>第三十六章</h2><p>异步模块模式（AMD - Asynchronous Module Definition）</p>
<ul>
<li>1.js - 异步模块模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line">(<span class="function"><span class="keyword">function</span> (<span class="params">F</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> moduleCache = &#123;&#125;;</span><br><span class="line">  <span class="keyword">var</span> getUrl = <span class="function"><span class="keyword">function</span> (<span class="params">moduleName</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">String</span>(moduleName).replace(<span class="regexp">/\.js$/g</span>, <span class="string">''</span>) + <span class="string">'.js'</span>;</span><br><span class="line">  &#125;;</span><br><span class="line">  <span class="keyword">var</span> loadScript = <span class="function"><span class="keyword">function</span> (<span class="params">src</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _script = <span class="built_in">document</span>.createElement(<span class="string">'script'</span>);</span><br><span class="line">    _script.type = <span class="string">'text/javascript'</span>;</span><br><span class="line">    _script.charset = <span class="string">'UTF-8'</span>;</span><br><span class="line">    _script.async = <span class="literal">true</span>;</span><br><span class="line">    _script.src = src;</span><br><span class="line">    <span class="built_in">document</span>.getElementsByTagName(<span class="string">'head'</span>)[<span class="number">0</span>].appendChild(_script);</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> loadModule = <span class="function"><span class="keyword">function</span> (<span class="params">moduleName, cb</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _module;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (moduleCache[moduleName]) &#123;</span><br><span class="line">      _module = moduleCache[moduleName];</span><br><span class="line"></span><br><span class="line">      <span class="keyword">if</span> (_module.status === <span class="string">'loaded'</span>) &#123;</span><br><span class="line">        setTimeout(cb(_module.exports), <span class="number">0</span>);</span><br><span class="line">      &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">        _module.onload.push(cb);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      moduleCache[moduleName] = &#123;</span><br><span class="line">        moduleName: moduleName,</span><br><span class="line">        status: <span class="string">'loading'</span>,</span><br><span class="line">        exports: <span class="literal">null</span>,</span><br><span class="line">        onload: [cb]</span><br><span class="line">      &#125;;</span><br><span class="line"></span><br><span class="line">      loadScript(getUrl(moduleName));</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">var</span> setModule = <span class="function"><span class="keyword">function</span> (<span class="params">moduleName, params, cb</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _module, fn;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (moduleCache[moduleName]) &#123;</span><br><span class="line">      _module = moduleCache[moduleName];</span><br><span class="line">      _module.status = <span class="string">'loaded'</span>;</span><br><span class="line">      _module.exports = cb ? cb.apply(_module, params) : <span class="literal">null</span>;</span><br><span class="line"></span><br><span class="line">      <span class="keyword">while</span> (fn = _module.onload.shift()) &#123;</span><br><span class="line">        fn(_module.exports);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      cb &amp;&amp; cb.apply(<span class="literal">null</span>, params);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">  F.module = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> args = <span class="built_in">Array</span>.prototype.slice.call(<span class="built_in">arguments</span>);</span><br><span class="line">    <span class="keyword">var</span> callback = args.pop();</span><br><span class="line">    <span class="keyword">var</span> deps = (args.length &amp;&amp; args[args.length - <span class="number">1</span>] <span class="keyword">instanceof</span> <span class="built_in">Array</span>) ? args.pop() : [];</span><br><span class="line">    <span class="keyword">var</span> url = args.length ? args.pop() : <span class="literal">null</span>;</span><br><span class="line">    <span class="keyword">var</span> params = [];</span><br><span class="line">    <span class="keyword">var</span> depsCount = <span class="number">0</span>;</span><br><span class="line">    <span class="keyword">var</span> len;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (len = deps.length) &#123;</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; len; i++) &#123;</span><br><span class="line">        (<span class="function"><span class="keyword">function</span> (<span class="params">i</span>) </span>&#123;</span><br><span class="line">          depsCount++;</span><br><span class="line">          loadModule(deps[i], <span class="function"><span class="keyword">function</span> (<span class="params">mod</span>) </span>&#123;</span><br><span class="line">            params[i] = mod;</span><br><span class="line">            depsCount--;</span><br><span class="line"></span><br><span class="line">            <span class="keyword">if</span> (depsCount === <span class="number">0</span>) &#123;</span><br><span class="line">              setModule(url, params, callback);</span><br><span class="line">            &#125;</span><br><span class="line">          &#125;);</span><br><span class="line">        &#125;)(i);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      setModule(url, [], callback);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">&#125;)((<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="built_in">window</span>.F = &#123;&#125;;</span><br><span class="line">&#125;)());</span><br></pre></td></tr></table></figure>

<figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br></pre></td><td class="code"><pre><span class="line">index.html</span><br><span class="line"></span><br><span class="line"><span class="meta">&lt;!DOCTYPE <span class="meta-keyword">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">html</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">head</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">meta</span> <span class="attr">charset</span>=<span class="string">"UTF-8"</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">title</span>&gt;</span>test<span class="tag">&lt;/<span class="name">title</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">head</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;<span class="name">body</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span> <span class="attr">src</span>=<span class="string">"../1.js"</span>&gt;</span><span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line">  <span class="tag">&lt;<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="actionscript">  F.module([<span class="string">'test'</span>, <span class="string">'test2'</span>], <span class="function"><span class="keyword">function</span> <span class="params">(test, test2)</span> </span>&#123;</span></span><br><span class="line"><span class="javascript">    <span class="built_in">console</span>.log(<span class="built_in">arguments</span>);</span></span><br><span class="line">  &#125;);</span><br><span class="line">  <span class="tag">&lt;/<span class="name">script</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">body</span>&gt;</span></span><br><span class="line"><span class="tag">&lt;/<span class="name">html</span>&gt;</span></span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//test.js</span></span><br><span class="line">F.module(<span class="string">'test'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    a: <span class="string">'123'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">//test2.js</span></span><br><span class="line"></span><br><span class="line">F.module(<span class="string">'test2'</span>, <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    a: <span class="string">'456'</span></span><br><span class="line">  &#125;</span><br><span class="line">&#125;);</span><br></pre></td></tr></table></figure>

<h2 id="第三十七章"><a href="#第三十七章" class="headerlink" title="第三十七章"></a>第三十七章</h2><p>Widget模式：Widget模式是指借用 Web Widget 思想将页面分解成组件，针对部件开发，最终整合成完整的页面。</p>
<p>PS：这章其实是演示了一下如何实现一个模板引擎。。。。</p>
<ul>
<li>1.js - 模板引擎模块</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br><span class="line">66</span><br><span class="line">67</span><br><span class="line">68</span><br><span class="line">69</span><br><span class="line">70</span><br><span class="line">71</span><br><span class="line">72</span><br><span class="line">73</span><br><span class="line">74</span><br><span class="line">75</span><br><span class="line">76</span><br><span class="line">77</span><br><span class="line">78</span><br><span class="line">79</span><br><span class="line">80</span><br><span class="line">81</span><br><span class="line">82</span><br><span class="line">83</span><br><span class="line">84</span><br><span class="line">85</span><br><span class="line">86</span><br><span class="line">87</span><br><span class="line">88</span><br><span class="line">89</span><br><span class="line">90</span><br><span class="line">91</span><br><span class="line">92</span><br><span class="line">93</span><br><span class="line">94</span><br><span class="line">95</span><br><span class="line">96</span><br><span class="line">97</span><br><span class="line">98</span><br><span class="line">99</span><br><span class="line">100</span><br><span class="line">101</span><br><span class="line">102</span><br><span class="line">103</span><br><span class="line">104</span><br><span class="line">105</span><br><span class="line">106</span><br><span class="line">107</span><br><span class="line">108</span><br><span class="line">109</span><br><span class="line">110</span><br><span class="line">111</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> tplEngine = &#123;</span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 获取模板</span></span><br><span class="line"><span class="comment">   *</span></span><br><span class="line"><span class="comment">   * @param str 模板容器ID或模板字符串</span></span><br><span class="line"><span class="comment">   * @return str 最终结果</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  getTpl: <span class="function"><span class="keyword">function</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> ele = (<span class="keyword">typeof</span> <span class="built_in">module</span> === <span class="string">'object'</span> &amp;&amp; <span class="built_in">module</span>.exports) ? <span class="literal">false</span> : <span class="built_in">document</span>.getElementById(str);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">if</span> (ele) &#123;</span><br><span class="line">      <span class="keyword">var</span> html = <span class="regexp">/textarea|input/i</span>.test(ele.nodeName) ? ele.value : ele.innerHTML;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>.compileTpl(html);</span><br><span class="line">    &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>.compileTpl(str);</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 处理模板</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  dealTpl: <span class="function"><span class="keyword">function</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> _left = <span class="string">'&#123;%'</span>;</span><br><span class="line">    <span class="keyword">var</span> _right = <span class="string">'%&#125;'</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="built_in">String</span>(str)</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 转义</span></span><br><span class="line">      .replace(<span class="regexp">/&amp;lt;/g</span>, <span class="string">'&lt;'</span>)</span><br><span class="line">      .replace(<span class="regexp">/&amp;gt;/g</span>, <span class="string">'&gt;'</span>)</span><br><span class="line">      </span><br><span class="line">      <span class="comment">// 过滤回车，制表符，回车符</span></span><br><span class="line">      .replace(<span class="regexp">/[\r|\t|\n]/g</span>, <span class="string">''</span>)</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 替换内容</span></span><br><span class="line">      .replace(<span class="keyword">new</span> <span class="built_in">RegExp</span>(_left+<span class="string">'=(.*?)'</span>+_right, <span class="string">'g'</span>), <span class="string">"',typeof($1)==='undefined'?'':$1,'"</span>)</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 替换左分隔符</span></span><br><span class="line">      .replace(<span class="keyword">new</span> <span class="built_in">RegExp</span>(_left, <span class="string">'g'</span>), <span class="string">"');"</span>)</span><br><span class="line"></span><br><span class="line">      <span class="comment">// 替换右分隔符</span></span><br><span class="line">      .replace(<span class="keyword">new</span> <span class="built_in">RegExp</span>(_right, <span class="string">'g'</span>), <span class="string">"template_array.push('"</span>);</span><br><span class="line">  &#125;,</span><br><span class="line"></span><br><span class="line">  <span class="comment">/*</span></span><br><span class="line"><span class="comment">   * 编译模板</span></span><br><span class="line"><span class="comment">   */</span></span><br><span class="line">  compileTpl: <span class="function"><span class="keyword">function</span>(<span class="params">str</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> fnBody = [</span><br><span class="line">      <span class="string">"var template_array=[];\n"</span>,</span><br><span class="line">      <span class="string">"var fn=(function(data)&#123;\n"</span>,</span><br><span class="line">        <span class="string">"var template_key='';\n"</span>,</span><br><span class="line">        <span class="string">"for(key in data)&#123;\n"</span>,</span><br><span class="line">          <span class="string">"template_key+=('var '+key+'=data[\"'+key+'\"];');\n"</span>,</span><br><span class="line">        <span class="string">"&#125;\n"</span>,</span><br><span class="line">        <span class="string">"eval(template_key);\n"</span>,</span><br><span class="line">        <span class="string">"template_array.push('"</span>+<span class="keyword">this</span>.dealTpl(str)+<span class="string">"');\n"</span>,</span><br><span class="line">        <span class="string">"template_key=null;\n"</span>,</span><br><span class="line">        <span class="string">"&#125;)(templateData);\n"</span>,</span><br><span class="line">      <span class="string">"fn=null;\n"</span>,</span><br><span class="line">      <span class="string">"return template_array.join('');"</span></span><br><span class="line">    ].join(<span class="string">''</span>);</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> <span class="keyword">new</span> <span class="built_in">Function</span>(<span class="string">'templateData'</span>, fnBody);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">/*</span></span><br><span class="line"><span class="comment"> * 模板引擎</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @param str 模板容器ID或模板字符串</span></span><br><span class="line"><span class="comment"> * @param data 数据</span></span><br><span class="line"><span class="comment"> *</span></span><br><span class="line"><span class="comment"> * @return 处理好的html</span></span><br><span class="line"><span class="comment"> */</span></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">template</span>(<span class="params">str, data</span>) </span>&#123;</span><br><span class="line">  <span class="keyword">if</span> (<span class="built_in">Object</span>.prototype.toString.call(data) === <span class="string">'[object Array]'</span>) &#123;</span><br><span class="line">    <span class="keyword">var</span> html = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">for</span> (<span class="keyword">var</span> i = <span class="number">0</span>; i &lt; data.length; i++) &#123;</span><br><span class="line">      html += tplEngine.getTpl(str)(data[i]);</span><br><span class="line">    &#125;</span><br><span class="line"></span><br><span class="line">    <span class="keyword">return</span> html;</span><br><span class="line">  &#125; <span class="keyword">else</span> &#123;</span><br><span class="line">    <span class="keyword">return</span> tplEngine.getTpl(str)(data);</span><br><span class="line">  &#125;</span><br><span class="line">&#125;</span><br><span class="line"></span><br><span class="line"><span class="comment">// test</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> data = &#123;</span><br><span class="line">  tagCloud: [</span><br><span class="line">    &#123;<span class="attr">selected</span>: <span class="literal">true</span>, <span class="attr">title</span>: <span class="string">'这是一本设计模式书'</span>, <span class="attr">text</span>: <span class="string">'设计模式'</span>&#125;,</span><br><span class="line">    &#123;<span class="attr">selected</span>: <span class="literal">false</span>, <span class="attr">title</span>: <span class="string">'这是一本Nodejs书'</span>, <span class="attr">text</span>: <span class="string">'Node.js'</span>&#125;,</span><br><span class="line">    &#123;<span class="attr">selected</span>: <span class="literal">false</span>, <span class="attr">title</span>: <span class="string">'这是一本javascript书'</span>, <span class="attr">text</span>: <span class="string">'javascript'</span>&#125;</span><br><span class="line">  ]</span><br><span class="line">&#125;;</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> str = [</span><br><span class="line">  <span class="string">'&lt;div&gt;'</span>,</span><br><span class="line">  <span class="string">'&#123;% for (var i = 0; i &lt; tagCloud.length; i++)&#123; %&#125;'</span>,</span><br><span class="line">    <span class="string">'&lt;a href="#" class="&#123;% if (tagCloud[i].selected)&#123; %&#125;selected&#123;% &#125; %&#125;" title="&#123;%= tagCloud[i].title %&#125;"&gt;&#123;%= tagCloud[i].text %&#125;&lt;/a&gt;'</span>,</span><br><span class="line">  <span class="string">'&#123;% &#125; %&#125;'</span>,</span><br><span class="line">  <span class="string">'&lt;/div&gt;'</span></span><br><span class="line">].join(<span class="string">''</span>);</span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> html = template(str, data);</span><br><span class="line"><span class="built_in">console</span>.log(html);</span><br></pre></td></tr></table></figure>

<h2 id="第三十八章"><a href="#第三十八章" class="headerlink" title="第三十八章"></a>第三十八章</h2><p>MVC模式：model(模型) - view(视图) - controller(控制器)</p>
<ul>
<li>1.js - MVC模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br><span class="line">62</span><br><span class="line">63</span><br><span class="line">64</span><br><span class="line">65</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 初始化MVC对象</span></span><br><span class="line"><span class="keyword">var</span> MVC = MVC || &#123;&#125;;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 数据模型层</span></span><br><span class="line">MVC.model = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 内部数据对象</span></span><br><span class="line">  <span class="keyword">var</span> M = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 服务端获取的数据，通常通过ajax获取并存储</span></span><br><span class="line">  <span class="comment">// 缓存起来，减少异步请求操作</span></span><br><span class="line">  M.data = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 配置数据，页面加载时即提供</span></span><br><span class="line">  M.conf = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    getData: <span class="function"><span class="keyword">function</span> (<span class="params">m</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> M.data[m];</span><br><span class="line">    &#125;,</span><br><span class="line">    getConf: <span class="function"><span class="keyword">function</span> (<span class="params">c</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> M.conf[c];</span><br><span class="line">    &#125;,</span><br><span class="line">    setData: <span class="function"><span class="keyword">function</span> (<span class="params">m, v</span>) </span>&#123;</span><br><span class="line">      M.data[m] = v;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;,</span><br><span class="line">    setConf: <span class="function"><span class="keyword">function</span> (<span class="params">c, v</span>) </span>&#123;</span><br><span class="line">      M.conf[c] = v;</span><br><span class="line">      <span class="keyword">return</span> <span class="keyword">this</span>;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 视图层</span></span><br><span class="line">MVC.view = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 模型数据层对象操作方法引用</span></span><br><span class="line">  <span class="keyword">var</span> M = MVC.model;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 内部视图创建方法</span></span><br><span class="line">  <span class="keyword">var</span> V = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">v</span>) </span>&#123;</span><br><span class="line">    <span class="comment">// 根据视图名称返回视图（由于获取的是一个方法，所以需要执行一边方法获取视图）</span></span><br><span class="line">    V[v]();</span><br><span class="line">  &#125;;</span><br><span class="line"></span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line"><span class="comment">// 控制器层</span></span><br><span class="line">MVC.ctrl = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 模型数据层对象操作方法引用</span></span><br><span class="line">  <span class="keyword">var</span> M = MVC.model;</span><br><span class="line">  <span class="comment">// 视图层对象操作方法引用</span></span><br><span class="line">  <span class="keyword">var</span> V = MVC.view;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 控制器创建方法对象</span></span><br><span class="line">  <span class="keyword">var</span> C = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 执行</span></span><br><span class="line">  <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> C) &#123;</span><br><span class="line">    C[i] &amp;&amp; C[i]();</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br></pre></td></tr></table></figure>

<h2 id="第三十九章"><a href="#第三十九章" class="headerlink" title="第三十九章"></a>第三十九章</h2><p>MVP模式：model(模型) - view(视图) - Presenter(管理器)，view层不能直接引用model层内的数据，二是通过presenter层实现对model层内的数据访问，即所有层次的交互都发生在presenter层中</p>
<ul>
<li>1.js - MVP模式</li>
</ul>
<figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br><span class="line">53</span><br><span class="line">54</span><br><span class="line">55</span><br><span class="line">56</span><br><span class="line">57</span><br><span class="line">58</span><br><span class="line">59</span><br><span class="line">60</span><br><span class="line">61</span><br></pre></td><td class="code"><pre><span class="line"><span class="meta">'use strict'</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// 只是搭建一个大题的架构，落实到具体功能上的例子在书中查看~~</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">var</span> MVP = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;&#125;;</span><br><span class="line"></span><br><span class="line">MVP.model = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="comment">// 内部数据对象</span></span><br><span class="line">  <span class="keyword">var</span> M = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 服务端获取的数据，通常通过ajax获取并存储</span></span><br><span class="line">  <span class="comment">// 缓存起来，减少异步请求操作</span></span><br><span class="line">  M.data = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="comment">// 配置数据，页面加载时即提供</span></span><br><span class="line">  M.conf = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    getData: <span class="function"><span class="keyword">function</span> (<span class="params">m</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> M.data[m];</span><br><span class="line">    &#125;,</span><br><span class="line">    getConf: <span class="function"><span class="keyword">function</span> (<span class="params">c</span>) </span>&#123;</span><br><span class="line">      <span class="keyword">return</span> M.conf[c];</span><br><span class="line">    &#125;,</span><br><span class="line">    setData: <span class="function"><span class="keyword">function</span> (<span class="params">m, v</span>) </span>&#123;</span><br><span class="line">      M.data[m] = v;</span><br><span class="line">      <span class="keyword">return</span> v;</span><br><span class="line">    &#125;,</span><br><span class="line">    setConf: <span class="function"><span class="keyword">function</span> (<span class="params">c, v</span>) </span>&#123;</span><br><span class="line">      M.conf[c] = v;</span><br><span class="line">      <span class="keyword">return</span> v;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line">MVP.view = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">str</span>) </span>&#123;</span><br><span class="line">    <span class="keyword">var</span> html = <span class="string">''</span>;</span><br><span class="line"></span><br><span class="line">    <span class="comment">// 将参数字符串转换成期望模板</span></span><br><span class="line">    <span class="keyword">return</span> html;</span><br><span class="line">  &#125;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line">MVP.presenter = (<span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">var</span> V = MVP.view;</span><br><span class="line">  <span class="keyword">var</span> M = MVP.model;</span><br><span class="line">  <span class="keyword">var</span> C = &#123;&#125;;</span><br><span class="line"></span><br><span class="line">  <span class="keyword">return</span> &#123;</span><br><span class="line">    init: <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">      <span class="keyword">for</span> (<span class="keyword">var</span> i <span class="keyword">in</span> C) &#123;</span><br><span class="line">        C[i] &amp;&amp; C[i](M, V, i);</span><br><span class="line">      &#125;</span><br><span class="line">    &#125;</span><br><span class="line">  &#125;;</span><br><span class="line">&#125;)();</span><br><span class="line"></span><br><span class="line">MVP.init = <span class="function"><span class="keyword">function</span> (<span class="params"></span>) </span>&#123;</span><br><span class="line">  <span class="keyword">this</span>.presenter.init();</span><br><span class="line">&#125;;</span><br></pre></td></tr></table></figure>


      
    </div>
    <div id="comments">
      <blockquote class="mt-2x">
  <ul class="post-copyright list-unstyled">
    
    <li class="post-copyright-link hidden-xs">
      <strong>本文链接：</strong>
      <a style="word-wrap:break-word;" href="http://yoursite.com/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/" title="JavaScript设计模式-学习" target="_blank" rel="external">http://yoursite.com/2019/11/24/01/javascript%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/</a>
    </li>
    
    <li class="post-copyright-license">
      <strong>版权声明： </strong> 本博客所有文章除特别声明外，均采用 <a href="http://creativecommons.org/licenses/by/4.0/deed.zh" target="_blank" rel="external">CC BY 4.0 CN协议</a> 许可协议。转载请注明出处！
    </li>
  </ul>
</blockquote>


<div class="panel panel-default panel-badger">
  <div class="panel-body">
    <figure class="media">
      <div class="media-left">
        <a href="https://github.com/chen08" target="_blank" class="img-burn thumb-sm visible-lg">
          <img src="/images/avatar.jpg" class="img-rounded w-full" alt="">
        </a>
      </div>
      <div class="media-body">
        <h3 class="media-heading"><a href="https://github.com/chen08" target="_blank"><span class="text-dark">溟海</span><small class="ml-1x">Web Developer &amp; Designer</small></a></h3>
        <div>天行健，君子以自强不息，地势坤，君子以厚德载物。 杀不死我的,终将使我强大 没有吃不了的苦,只有享不了的福</div>
      </div>
    </figure>
  </div>
</div>


    </div>
  </article>
  
    
  <section id="comments">
  	
      <div id="vcomments"></div>
    
  </section>


  
</div>

  <nav class="bar bar-footer clearfix" data-stick-bottom>
  <div class="bar-inner">
  
  <ul class="pager pull-left">
    
    <li class="prev">
      <a href="/2020/03/09/01/JavaScript/" title="JavaScript资料"><i class="icon icon-angle-left" aria-hidden="true"></i><span>&nbsp;&nbsp;Newer</span></a>
    </li>
    
    
    <li class="next">
      <a href="/2019/11/08/03/3.%E4%BA%A7%E5%93%81%E8%AE%BE%E8%AE%A1/" title="Hello World"><span>Older&nbsp;&nbsp;</span><i class="icon icon-angle-right" aria-hidden="true"></i></a>
    </li>
    
    
    <li class="toggle-toc">
      <a class="toggle-btn collapsed" data-toggle="collapse" href="#collapseToc" aria-expanded="false" title="Catalogue" role="button">
        <span>[&nbsp;</span><span>Catalogue</span>
        <i class="text-collapsed icon icon-anchor"></i>
        <i class="text-in icon icon-close"></i>
        <span>]</span>
      </a>
    </li>
    
  </ul>
  
  
  <!-- Button trigger modal -->
  <button type="button" class="btn btn-fancy btn-donate pop-onhover bg-gradient-warning" data-toggle="modal" data-target="#donateModal"><span>$</span></button>
  <!-- <div class="wave-icon wave-icon-danger btn-donate" data-toggle="modal" data-target="#donateModal">
    <div class="wave-circle"><span class="icon"><i class="icon icon-bill"></i></span></div>
  </div> -->
  
  
  <div class="bar-right">
    
    <div class="share-component" data-sites="weibo,qq,wechat,facebook,twitter" data-mobile-sites="weibo,qq,qzone"></div>
    
  </div>
  </div>
</nav>
  
<!-- Modal -->
<div class="modal modal-center modal-small modal-xs-full fade" id="donateModal" tabindex="-1" role="dialog">
  <div class="modal-dialog" role="document">
    <div class="modal-content donate">
      <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
      <div class="modal-body">
        <div class="donate-box">
          <div class="donate-head">
            <p>Maybe you could buy me a cup of coffee.</p>
          </div>
          <div class="tab-content">
            <div role="tabpanel" class="tab-pane fade active in" id="alipay">
              <div class="donate-payimg">
                <img src="/images/donate/alipayimg.png" alt="Scan Qrcode" title="Scan" />
              </div>
              <p class="text-muted mv">Scan this qrcode</p>
              <p class="text-grey">Open alipay app scan this qrcode, buy me a coffee!</p>
            </div>
            <div role="tabpanel" class="tab-pane fade" id="wechatpay">
              <div class="donate-payimg">
                <img src="/images/donate/wechatpayimg.png" alt="Scan Qrcode" title="Scan" />
              </div>
              <p class="text-muted mv">Scan this qrcode</p>
              <p class="text-grey">Open wechat app scan this qrcode, buy me a coffee!</p>
            </div>
          </div>
          <div class="donate-footer">
            <ul class="nav nav-tabs nav-justified" role="tablist">
              <li role="presentation" class="active">
                <a href="#alipay" id="alipay-tab" role="tab" data-toggle="tab" aria-controls="alipay" aria-expanded="true"><i class="icon icon-alipay"></i> alipay</a>
              </li>
              <li role="presentation" class="">
                <a href="#wechatpay" role="tab" id="wechatpay-tab" data-toggle="tab" aria-controls="wechatpay" aria-expanded="false"><i class="icon icon-wepay"></i> wechat payment</a>
              </li>
            </ul>
          </div>
        </div>
      </div>
    </div>
  </div>
</div>



</main>

  <footer class="footer" itemscope itemtype="http://schema.org/WPFooter">
	
	
    <ul class="social-links">
    	
        <li><a href="https://github.com/cofess" target="_blank" title="Github" data-toggle=tooltip data-placement=top><i class="icon icon-github"></i></a></li>
        
        <li><a href="http://weibo.com/cofess" target="_blank" title="Weibo" data-toggle=tooltip data-placement=top><i class="icon icon-weibo"></i></a></li>
        
        <li><a href="https://twitter.com/iwebued" target="_blank" title="Twitter" data-toggle=tooltip data-placement=top><i class="icon icon-twitter"></i></a></li>
        
        <li><a href="https://www.behance.net/cofess" target="_blank" title="Behance" data-toggle=tooltip data-placement=top><i class="icon icon-behance"></i></a></li>
        
        <li><a href="/atom.xml" target="_blank" title="Rss" data-toggle=tooltip data-placement=top><i class="icon icon-rss"></i></a></li>
        
    </ul>

    <div class="copyright">
    	
        <div class="publishby">
        	Theme by <a href="https://github.com/cofess" target="_blank"> cofess </a>base on <a href="https://github.com/cofess/hexo-theme-pure" target="_blank">pure</a>.
        </div>
    </div>
</footer>
  <script src="//cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<script>
window.jQuery || document.write('<script src="js/jquery.min.js"><\/script>')
</script>

<script src="/js/plugin.min.js"></script>


<script src="/js/application.js"></script>


    <script>
(function (window) {
    var INSIGHT_CONFIG = {
        TRANSLATION: {
            POSTS: 'Posts',
            PAGES: 'Pages',
            CATEGORIES: 'Categories',
            TAGS: 'Tags',
            UNTITLED: '(Untitled)',
        },
        ROOT_URL: '/',
        CONTENT_URL: '/content.json',
    };
    window.INSIGHT_CONFIG = INSIGHT_CONFIG;
})(window);
</script>

<script src="/js/insight.js"></script>






   


<!-- custom analytics part create by xiamo -->
<script  src="https://cdn1.lncld.net/static/js/av-min-1.2.1.js"></script>
<!-- <script defer src="/js/av-min-1.2.1.js"></script> -->
<script >
AV.init({
  appId: 'ngFQzHw7z0HgQfrtn4En4WTN-gzGzoHsz',
  appKey: 'W9hgBBfVDwRGJKoGp5a6HKpx'
});

function showTime(Counter) {
	var query = new AV.Query(Counter);
		var visitors= $('.leancloud_visitors');
		query.greaterThanOrEqualTo("time", 0);		
		query.find({
			success: function(results) {
				if (results.length == 0) {				
					return;
				}
				var data = results;
				visitors.each(function(){
					var url = $(this).attr('id').trim();					
					for (var i = 0; i < data.length; i++) {
						var object = data[i];
						var content = object.get('time');
						var _url = object.get('url')
						if(url == _url){
							$(this).text(content);
						}
					}
				})
				
			},
			error: function(object, error) {
				console.log("Error: " + error.code + " " + error.message);
			}
		});
}

function addCount(Counter) {
	var Counter = AV.Object.extend("Counter");
	url = $(".leancloud_visitors").attr('id').trim();
	title = $(".leancloud_visitors").attr('data-flag-title').trim();
	var query = new AV.Query(Counter);
	query.equalTo("url", url);
	query.find({
		success: function(results) {
			if (results.length > 0) {
				var counter = results[0];
				counter.fetchWhenSave(true);
				counter.increment("time");
				counter.save(null, {
					success: function(counter) {
						var content = counter.get('time');
						$(document.getElementById(url)).text(content);
					},
					error: function(counter, error) {
						console.log('Failed to save Visitor num, with error message: ' + error.message);
					}
				});
			} else {
				var newcounter = new Counter();
				newcounter.set("title", title);
				newcounter.set("url", url);
				newcounter.set("time", 1);
				newcounter.save(null, {
					success: function(newcounter) {
					    console.log("newcounter.get('time')="+newcounter.get('time'));
						var content = newcounter.get('time');
						$(document.getElementById(url)).text(content);
					},
					error: function(newcounter, error) {
						console.log('Failed to create');
					}
				});
			}
		},
		error: function(error) {
			console.log('Error:' + error.code + " " + error.message);
		}
	});
}
$(function() {
	var Counter = AV.Object.extend("Counter");
	if ($('.leancloud_visitors').length == 1) {
		addCount(Counter);
	} else {
		showTime(Counter);
	}
}); 
</script>



   
    
  <!-- <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script> -->
  <script src="//cdn.jsdelivr.net/npm/valine"></script>
  <script type="text/javascript">
  var GUEST = ['nick', 'mail', 'link'];
  var meta = 'nick,mail,link';
  meta = meta.split(',').filter(function(item) {
    return GUEST.indexOf(item) > -1;
  });
  new Valine({
    el: '#vcomments',
    verify: false,
    notify: false,
    appId: '',
    appKey: '',
    placeholder: 'Just go go',
    avatar: 'mm',
    meta: meta,
    pageSize: '10' || 10,
    visitor: false
  });
  </script>

     







</body>
</html>